From 819414df026a966d3f49471ff3fa0879572e513f Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Tue, 22 Oct 2019 18:19:22 +0200 Subject: [PATCH] Add test infrastructure with shared tables This PR adds test infrastructure for running tests with shared tables. This allows having hypertables with specific configurations usable for all tests. Since these tests also don't require creating a new database for each test case some of the overhead of the normal tests is removed. While this will lead to much faster query tests some tests will still require their own database to test things, but most queres could be moved to this infrastructure to improve test coverage and speed them up. --- test/expected/plan_ordered_append-10.out | 1809 +--- test/expected/plan_ordered_append-11.out | 1809 +--- test/expected/plan_ordered_append-9.6.out | 1760 +--- test/runner_shared.sh | 46 + test/sql/CMakeLists.txt | 5 - test/sql/include/plan_ordered_append_load.sql | 23 - .../sql/include/plan_ordered_append_query.sql | 373 - test/test-defs.cmake | 18 + tsl/test/CMakeLists.txt | 39 +- tsl/test/isolation/specs/CMakeLists.txt | 22 +- tsl/test/shared/CMakeLists.txt | 1 + .../shared/expected/ordered_append-10.out | 7900 ++++++++++++++++ .../shared/expected/ordered_append-11.out | 7903 +++++++++++++++++ tsl/test/shared/sql/.gitignore | 2 + tsl/test/shared/sql/CMakeLists.txt | 33 + .../sql/include/ordered_append_query.sql | 314 + tsl/test/shared/sql/include/shared_setup.sql | 70 + tsl/test/shared/sql/ordered_append-11.sql | 72 + tsl/test/shared/sql/ordered_append.sql.in | 72 + tsl/test/sql/CMakeLists.txt | 79 +- 20 files changed, 17071 insertions(+), 5279 deletions(-) create mode 100755 test/runner_shared.sh create mode 100644 tsl/test/shared/CMakeLists.txt create mode 100644 tsl/test/shared/expected/ordered_append-10.out create mode 100644 tsl/test/shared/expected/ordered_append-11.out create mode 100644 tsl/test/shared/sql/.gitignore create mode 100644 tsl/test/shared/sql/CMakeLists.txt create mode 100644 tsl/test/shared/sql/include/ordered_append_query.sql create mode 100644 tsl/test/shared/sql/include/shared_setup.sql create mode 100644 tsl/test/shared/sql/ordered_append-11.sql create mode 100644 tsl/test/shared/sql/ordered_append.sql.in diff --git a/test/expected/plan_ordered_append-10.out b/test/expected/plan_ordered_append-10.out index 3eb802294..4fc27da66 100644 --- a/test/expected/plan_ordered_append-10.out +++ b/test/expected/plan_ordered_append-10.out @@ -42,25 +42,12 @@ INSERT INTO devices VALUES (1,'Device 1'), (2,'Device 2'), (3,'Device 3'); --- create a table where we create chunks in order -CREATE TABLE ordered_append(time timestamptz NOT NULL, device_id INT, value float); -SELECT create_hypertable('ordered_append','time'); - create_hypertable ------------------------------ - (1,public,ordered_append,t) -(1 row) - -CREATE index on ordered_append(time DESC,device_id); -CREATE index on ordered_append(device_id,time DESC); -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 1, 0.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 2, 1.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 3, 2.5; -- create a second table where we create chunks in reverse order CREATE TABLE ordered_append_reverse(time timestamptz NOT NULL, device_id INT, value float); SELECT create_hypertable('ordered_append_reverse','time'); create_hypertable ------------------------------------- - (2,public,ordered_append_reverse,t) + (1,public,ordered_append_reverse,t) (1 row) INSERT INTO ordered_append_reverse SELECT generate_series('2000-01-18'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 0.5; @@ -74,7 +61,7 @@ CREATE TABLE IF NOT EXISTS dimension_last( SELECT create_hypertable('dimension_last', 'time', chunk_time_interval => interval '1day', if_not_exists => True); create_hypertable ----------------------------- - (3,public,dimension_last,t) + (2,public,dimension_last,t) (1 row) -- table with only dimension column @@ -84,7 +71,7 @@ CREATE TABLE IF NOT EXISTS dimension_only( SELECT create_hypertable('dimension_only', 'time', chunk_time_interval => interval '1day', if_not_exists => True); create_hypertable ----------------------------- - (4,public,dimension_only,t) + (3,public,dimension_only,t) (1 row) INSERT INTO dimension_last SELECT 1,1,'Device 1',generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-04 23:59:00+0'::timestamptz,'1m'::interval); @@ -94,7 +81,6 @@ INSERT INTO dimension_only VALUES ('2000-01-05'), ('2000-01-07'); ANALYZE devices; -ANALYZE ordered_append; ANALYZE ordered_append_reverse; ANALYZE dimension_last; ANALYZE dimension_only; @@ -103,7 +89,7 @@ CREATE TABLE ht_missing_indexes(time timestamptz NOT NULL, device_id int, value SELECT create_hypertable('ht_missing_indexes','time'); create_hypertable --------------------------------- - (5,public,ht_missing_indexes,t) + (4,public,ht_missing_indexes,t) (1 row) INSERT INTO ht_missing_indexes SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 1, 0.5; @@ -123,7 +109,7 @@ CREATE TABLE ht_dropped_columns(c1 int, c2 int, c3 int, c4 int, c5 int, time tim SELECT create_hypertable('ht_dropped_columns','time'); create_hypertable --------------------------------- - (6,public,ht_dropped_columns,t) + (5,public,ht_dropped_columns,t) (1 row) ALTER TABLE ht_dropped_columns DROP COLUMN c1; @@ -137,31 +123,17 @@ INSERT INTO ht_dropped_columns(time,device_id,value) SELECT generate_series('200 ALTER TABLE ht_dropped_columns DROP COLUMN c5; INSERT INTO ht_dropped_columns(time,device_id,value) SELECT generate_series('2000-01-29'::timestamptz,'2000-01-30'::timestamptz,'1m'::interval), 1, 0.5; ANALYZE ht_dropped_columns; -CREATE TABLE space(time timestamptz NOT NULL, device_id int NOT NULL, value float); -SELECT create_hypertable('space','time','device_id',number_partitions:=4); - create_hypertable --------------------- - (7,public,space,t) -(1 row) - -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 2, 2.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 3, 3.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 4, 4.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 5, 5.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 6, 6.5; -ANALYZE space; CREATE TABLE space2(time timestamptz NOT NULL, device_id int NOT NULL, tag_id int NOT NULL, value float); SELECT create_hypertable('space2','time','device_id',number_partitions:=3); create_hypertable --------------------- - (8,public,space2,t) + (6,public,space2,t) (1 row) SELECT add_dimension('space2','tag_id',number_partitions:=3); - add_dimension ------------------------------ - (11,public,space2,tag_id,t) + add_dimension +---------------------------- + (8,public,space2,tag_id,t) (1 row) INSERT INTO space2 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1, 1.5; @@ -178,19 +150,19 @@ CREATE TABLE space3(time timestamptz NOT NULL, x int NOT NULL, y int NOT NULL, z SELECT create_hypertable('space3','time','x',number_partitions:=2); create_hypertable --------------------- - (9,public,space3,t) + (7,public,space3,t) (1 row) SELECT add_dimension('space3','y',number_partitions:=2); add_dimension ------------------------ - (14,public,space3,y,t) + (11,public,space3,y,t) (1 row) SELECT add_dimension('space3','z',number_partitions:=2); add_dimension ------------------------ - (15,public,space3,z,t) + (12,public,space3,z,t) (1 row) INSERT INTO space3 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1, 1, 1.5; @@ -204,9 +176,9 @@ INSERT INTO space3 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01' ANALYZE space3; CREATE TABLE sortopt_test(time timestamptz NOT NULL, device TEXT); SELECT create_hypertable('sortopt_test','time',create_default_indexes:=false); - create_hypertable ----------------------------- - (10,public,sortopt_test,t) + create_hypertable +--------------------------- + (8,public,sortopt_test,t) (1 row) -- since alpine does not support locales we cant test collations in our ci @@ -232,105 +204,64 @@ FROM INNER JOIN _timescaledb_catalog.dimension d ON ds.dimension_id = d.id INNER JOIN _timescaledb_catalog.hypertable ht ON d.hypertable_id = ht.id ORDER BY ht.table_name, range_start, chunk; - hypertable | chunk | range_start -------------------------+--------------------+---------------------- - dimension_last | _hyper_3_7_chunk | 946684800000000 - dimension_last | _hyper_3_8_chunk | 946771200000000 - dimension_last | _hyper_3_9_chunk | 946857600000000 - dimension_last | _hyper_3_10_chunk | 946944000000000 - dimension_only | _hyper_4_11_chunk | 946684800000000 - dimension_only | _hyper_4_12_chunk | 946857600000000 - dimension_only | _hyper_4_13_chunk | 947030400000000 - dimension_only | _hyper_4_14_chunk | 947203200000000 - ht_dropped_columns | _hyper_6_18_chunk | 946512000000000 - ht_dropped_columns | _hyper_6_19_chunk | 947116800000000 - ht_dropped_columns | _hyper_6_20_chunk | 947721600000000 - ht_dropped_columns | _hyper_6_21_chunk | 948326400000000 - ht_dropped_columns | _hyper_6_22_chunk | 948931200000000 - ht_missing_indexes | _hyper_5_15_chunk | 946512000000000 - ht_missing_indexes | _hyper_5_16_chunk | 947116800000000 - ht_missing_indexes | _hyper_5_17_chunk | 947721600000000 - ordered_append | _hyper_1_1_chunk | 946512000000000 - ordered_append | _hyper_1_2_chunk | 947116800000000 - ordered_append | _hyper_1_3_chunk | 947721600000000 - ordered_append_reverse | _hyper_2_6_chunk | 946512000000000 - ordered_append_reverse | _hyper_2_5_chunk | 947116800000000 - ordered_append_reverse | _hyper_2_4_chunk | 947721600000000 - sortopt_test | _hyper_10_66_chunk | 946512000000000 - sortopt_test | _hyper_10_65_chunk | 947116800000000 - space | _hyper_7_24_chunk | -9223372036854775808 - space | _hyper_7_26_chunk | 946512000000000 - space | _hyper_7_28_chunk | 946512000000000 - space | _hyper_7_30_chunk | 946512000000000 - space | _hyper_7_23_chunk | 947116800000000 - space | _hyper_7_25_chunk | 947116800000000 - space | _hyper_7_27_chunk | 947116800000000 - space | _hyper_7_29_chunk | 947116800000000 - space2 | _hyper_8_32_chunk | -9223372036854775808 - space2 | _hyper_8_34_chunk | -9223372036854775808 - space2 | _hyper_8_36_chunk | -9223372036854775808 - space2 | _hyper_8_38_chunk | -9223372036854775808 - space2 | _hyper_8_44_chunk | -9223372036854775808 - space2 | _hyper_8_40_chunk | 946512000000000 - space2 | _hyper_8_42_chunk | 946512000000000 - space2 | _hyper_8_46_chunk | 946512000000000 - space2 | _hyper_8_48_chunk | 946512000000000 - space2 | _hyper_8_31_chunk | 947116800000000 - space2 | _hyper_8_33_chunk | 947116800000000 - space2 | _hyper_8_35_chunk | 947116800000000 - space2 | _hyper_8_37_chunk | 947116800000000 - space2 | _hyper_8_39_chunk | 947116800000000 - space2 | _hyper_8_41_chunk | 947116800000000 - space2 | _hyper_8_43_chunk | 947116800000000 - space2 | _hyper_8_45_chunk | 947116800000000 - space2 | _hyper_8_47_chunk | 947116800000000 - space3 | _hyper_9_50_chunk | -9223372036854775808 - space3 | _hyper_9_52_chunk | -9223372036854775808 - space3 | _hyper_9_54_chunk | -9223372036854775808 - space3 | _hyper_9_56_chunk | -9223372036854775808 - space3 | _hyper_9_58_chunk | -9223372036854775808 - space3 | _hyper_9_60_chunk | -9223372036854775808 - space3 | _hyper_9_62_chunk | -9223372036854775808 - space3 | _hyper_9_64_chunk | 946512000000000 - space3 | _hyper_9_49_chunk | 947116800000000 - space3 | _hyper_9_51_chunk | 947116800000000 - space3 | _hyper_9_53_chunk | 947116800000000 - space3 | _hyper_9_55_chunk | 947116800000000 - space3 | _hyper_9_57_chunk | 947116800000000 - space3 | _hyper_9_59_chunk | 947116800000000 - space3 | _hyper_9_61_chunk | 947116800000000 - space3 | _hyper_9_63_chunk | 947116800000000 -(66 rows) - --- test ASC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test DESC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) -(6 rows) + hypertable | chunk | range_start +------------------------+-------------------+---------------------- + dimension_last | _hyper_2_4_chunk | 946684800000000 + dimension_last | _hyper_2_5_chunk | 946771200000000 + dimension_last | _hyper_2_6_chunk | 946857600000000 + dimension_last | _hyper_2_7_chunk | 946944000000000 + dimension_only | _hyper_3_8_chunk | 946684800000000 + dimension_only | _hyper_3_9_chunk | 946857600000000 + dimension_only | _hyper_3_10_chunk | 947030400000000 + dimension_only | _hyper_3_11_chunk | 947203200000000 + ht_dropped_columns | _hyper_5_15_chunk | 946512000000000 + ht_dropped_columns | _hyper_5_16_chunk | 947116800000000 + ht_dropped_columns | _hyper_5_17_chunk | 947721600000000 + ht_dropped_columns | _hyper_5_18_chunk | 948326400000000 + ht_dropped_columns | _hyper_5_19_chunk | 948931200000000 + ht_missing_indexes | _hyper_4_12_chunk | 946512000000000 + ht_missing_indexes | _hyper_4_13_chunk | 947116800000000 + ht_missing_indexes | _hyper_4_14_chunk | 947721600000000 + ordered_append_reverse | _hyper_1_3_chunk | 946512000000000 + ordered_append_reverse | _hyper_1_2_chunk | 947116800000000 + ordered_append_reverse | _hyper_1_1_chunk | 947721600000000 + sortopt_test | _hyper_8_55_chunk | 946512000000000 + sortopt_test | _hyper_8_54_chunk | 947116800000000 + space2 | _hyper_6_21_chunk | -9223372036854775808 + space2 | _hyper_6_23_chunk | -9223372036854775808 + space2 | _hyper_6_25_chunk | -9223372036854775808 + space2 | _hyper_6_27_chunk | -9223372036854775808 + space2 | _hyper_6_33_chunk | -9223372036854775808 + space2 | _hyper_6_29_chunk | 946512000000000 + space2 | _hyper_6_31_chunk | 946512000000000 + space2 | _hyper_6_35_chunk | 946512000000000 + space2 | _hyper_6_37_chunk | 946512000000000 + space2 | _hyper_6_20_chunk | 947116800000000 + space2 | _hyper_6_22_chunk | 947116800000000 + space2 | _hyper_6_24_chunk | 947116800000000 + space2 | _hyper_6_26_chunk | 947116800000000 + space2 | _hyper_6_28_chunk | 947116800000000 + space2 | _hyper_6_30_chunk | 947116800000000 + space2 | _hyper_6_32_chunk | 947116800000000 + space2 | _hyper_6_34_chunk | 947116800000000 + space2 | _hyper_6_36_chunk | 947116800000000 + space3 | _hyper_7_39_chunk | -9223372036854775808 + space3 | _hyper_7_41_chunk | -9223372036854775808 + space3 | _hyper_7_43_chunk | -9223372036854775808 + space3 | _hyper_7_45_chunk | -9223372036854775808 + space3 | _hyper_7_47_chunk | -9223372036854775808 + space3 | _hyper_7_49_chunk | -9223372036854775808 + space3 | _hyper_7_51_chunk | -9223372036854775808 + space3 | _hyper_7_53_chunk | 946512000000000 + space3 | _hyper_7_38_chunk | 947116800000000 + space3 | _hyper_7_40_chunk | 947116800000000 + space3 | _hyper_7_42_chunk | 947116800000000 + space3 | _hyper_7_44_chunk | 947116800000000 + space3 | _hyper_7_46_chunk | 947116800000000 + space3 | _hyper_7_48_chunk | 947116800000000 + space3 | _hyper_7_50_chunk | 947116800000000 + space3 | _hyper_7_52_chunk | 947116800000000 +(55 rows) -- test ASC for reverse ordered chunks :PREFIX SELECT @@ -342,9 +273,9 @@ ORDER BY time ASC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ordered_append_reverse (actual rows=1 loops=1) Order: ordered_append_reverse."time" - -> Index Scan Backward using _hyper_2_6_chunk_ordered_append_reverse_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_2_5_chunk_ordered_append_reverse_time_idx on _hyper_2_5_chunk (never executed) - -> Index Scan Backward using _hyper_2_4_chunk_ordered_append_reverse_time_idx on _hyper_2_4_chunk (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_reverse_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_reverse_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_reverse_time_idx on _hyper_1_1_chunk (never executed) (6 rows) -- test DESC for reverse ordered chunks @@ -357,356 +288,9 @@ ORDER BY time DESC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ordered_append_reverse (actual rows=1 loops=1) Order: ordered_append_reverse."time" DESC - -> Index Scan using _hyper_2_4_chunk_ordered_append_reverse_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_2_5_chunk_ordered_append_reverse_time_idx on _hyper_2_5_chunk (never executed) - -> Index Scan using _hyper_2_6_chunk_ordered_append_reverse_time_idx on _hyper_2_6_chunk (never executed) -(6 rows) - --- test query with ORDER BY column not in targetlist -:PREFIX SELECT - device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- ORDER BY may include other columns after time column -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC, ordered_append.device_id - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_device_id_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_device_id_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_device_id_idx on _hyper_1_1_chunk (never executed) -(6 rows) - --- test RECORD in targetlist -:PREFIX SELECT - (time, device_id, value) -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC, ordered_append.device_id - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_device_id_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_device_id_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_device_id_idx on _hyper_1_1_chunk (never executed) -(6 rows) - --- test sort column not in targetlist -:PREFIX SELECT - time_bucket('1h',time) -FROM ordered_append -ORDER BY time DESC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Heap Fetches: 0 -(9 rows) - --- queries with ORDER BY non-time column shouldn't use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Merge Append (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) -(6 rows) - --- time column must be primary sort order -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id, time LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk.device_id, _hyper_1_1_chunk."time" - Sort Method: top-N heapsort - -> Append (actual rows=73443 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=20160 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=30240 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=23043 loops=1) -(8 rows) - --- queries without LIMIT should use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on ordered_append (actual rows=73443 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=20160 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=30240 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=23043 loops=1) -(5 rows) - --- queries without ORDER BY shouldnt use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -LIMIT 1; - QUERY PLAN ------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Append (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_2_chunk (never executed) - -> Seq Scan on _hyper_1_3_chunk (never executed) -(5 rows) - --- test interaction with constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) -(7 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) -(7 rows) - --- test interaction with constraint aware append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" > now_s()) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) - Index Cond: ("time" > now_s()) -(8 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" < now_s()) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" < now_s()) -(8 rows) - --- test constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() AND time < '2000-01-10' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: (("time" > now_s()) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) -(6 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() AND time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: (("time" < now_s()) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) -(6 rows) - --- min/max queries -:PREFIX SELECT max(time) FROM ordered_append; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------- - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 -(14 rows) - -:PREFIX SELECT min(time) FROM ordered_append; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Only Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 -(14 rows) - --- test first/last (doesn't use ordered append yet) -:PREFIX SELECT first(time, time) FROM ordered_append; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Result (actual rows=1 loops=1) - -> Merge Append (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk."time" - -> Index Only Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 -(15 rows) - -:PREFIX SELECT last(time, time) FROM ordered_append; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Result (actual rows=1 loops=1) - -> Merge Append (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk."time" DESC - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 -(15 rows) - --- test query with time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: time_bucket('@ 1 day'::interval, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time_bucket('1d',time) LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: time_bucket('@ 1 day'::interval, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) + -> Index Scan using _hyper_1_1_chunk_ordered_append_reverse_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_1_2_chunk_ordered_append_reverse_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan using _hyper_1_3_chunk_ordered_append_reverse_time_idx on _hyper_1_3_chunk (never executed) (6 rows) -- test query with ORDER BY time_bucket, device_id @@ -719,46 +303,16 @@ ORDER BY time_bucket('1d',time), device_id LIMIT 1; ----------------------------------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_3_7_chunk."time")), _hyper_3_7_chunk.device_id + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id Sort Method: top-N heapsort -> Result (actual rows=5760 loops=1) -> Append (actual rows=5760 loops=1) - -> Seq Scan on _hyper_3_7_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_8_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_9_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_10_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=1440 loops=1) (10 rows) --- test query with ORDER BY date_trunc -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY date_trunc('day', time) LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: date_trunc('day'::text, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test query with ORDER BY date_trunc -:PREFIX SELECT - date_trunc('day',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: date_trunc('day'::text, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - -- test query with ORDER BY date_trunc, device_id -- must not use ordered append :PREFIX SELECT @@ -769,111 +323,16 @@ ORDER BY 1,2 LIMIT 1; -------------------------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_3_7_chunk."time")), _hyper_3_7_chunk.device_id + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id Sort Method: top-N heapsort -> Result (actual rows=5760 loops=1) -> Append (actual rows=5760 loops=1) - -> Seq Scan on _hyper_3_7_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_8_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_9_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_10_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=1440 loops=1) (10 rows) --- test query with now() should result in ordered ChunkAppend -:PREFIX SELECT * FROM ordered_append WHERE time < now() + '1 month' -ORDER BY time DESC limit 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) -(10 rows) - --- test CTE -:PREFIX WITH i AS (SELECT * FROM ordered_append WHERE time < now() ORDER BY time DESC limit 100) -SELECT * FROM i; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - CTE Scan on i (actual rows=100 loops=1) - CTE i - -> Limit (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=100 loops=1) - Order: ordered_append."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=100 loops=1) - Index Cond: ("time" < now()) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" < now()) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" < now()) -(12 rows) - --- test LATERAL with ordered append in the outer query -:PREFIX SELECT * FROM ordered_append, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=2 loops=1) - -> Nested Loop (actual rows=2 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - -> Materialize (actual rows=2 loops=1) - -> Values Scan on "*VALUES*" (actual rows=2 loops=1) -(9 rows) - --- test LATERAL with ordered append in the lateral query -:PREFIX SELECT * FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM ordered_append ORDER BY time DESC limit 2) l; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- - Nested Loop (actual rows=4 loops=1) - -> Values Scan on "*VALUES*" (actual rows=2 loops=1) - -> Materialize (actual rows=2 loops=2) - -> Limit (actual rows=2 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=2 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=2 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) -(9 rows) - --- test plan with best index is chosen --- this should use device_id, time index -:PREFIX SELECT * FROM ordered_append WHERE device_id = 1 ORDER BY time DESC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: (device_id = 1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: (device_id = 1) - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: (device_id = 1) -(9 rows) - --- test plan with best index is chosen --- this should use time index -:PREFIX SELECT * FROM ordered_append ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) -(6 rows) - -- test with table with only dimension column :PREFIX SELECT * FROM dimension_only ORDER BY time DESC LIMIT 1; QUERY PLAN @@ -881,13 +340,13 @@ SELECT * FROM i; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on dimension_only (actual rows=1 loops=1) Order: dimension_only."time" DESC - -> Index Only Scan using _hyper_4_14_chunk_dimension_only_time_idx on _hyper_4_14_chunk (actual rows=1 loops=1) + -> Index Only Scan using _hyper_3_11_chunk_dimension_only_time_idx on _hyper_3_11_chunk (actual rows=1 loops=1) Heap Fetches: 1 - -> Index Only Scan using _hyper_4_13_chunk_dimension_only_time_idx on _hyper_4_13_chunk (never executed) + -> Index Only Scan using _hyper_3_10_chunk_dimension_only_time_idx on _hyper_3_10_chunk (never executed) Heap Fetches: 0 - -> Index Only Scan using _hyper_4_12_chunk_dimension_only_time_idx on _hyper_4_12_chunk (never executed) + -> Index Only Scan using _hyper_3_9_chunk_dimension_only_time_idx on _hyper_3_9_chunk (never executed) Heap Fetches: 0 - -> Index Only Scan using _hyper_4_11_chunk_dimension_only_time_idx on _hyper_4_11_chunk (never executed) + -> Index Only Scan using _hyper_3_8_chunk_dimension_only_time_idx on _hyper_3_8_chunk (never executed) Heap Fetches: 0 (11 rows) @@ -897,23 +356,23 @@ FROM dimension_last LEFT JOIN dimension_only USING (time) ORDER BY dimension_last.time DESC LIMIT 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Limit -> Nested Loop Left Join - Join Filter: (dimension_last."time" = _hyper_4_14_chunk."time") + Join Filter: (dimension_last."time" = _hyper_3_11_chunk."time") -> Custom Scan (ChunkAppend) on dimension_last Order: dimension_last."time" DESC - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk -> Materialize -> Append - -> Seq Scan on _hyper_4_14_chunk - -> Seq Scan on _hyper_4_13_chunk - -> Seq Scan on _hyper_4_12_chunk - -> Seq Scan on _hyper_4_11_chunk + -> Seq Scan on _hyper_3_11_chunk + -> Seq Scan on _hyper_3_10_chunk + -> Seq Scan on _hyper_3_9_chunk + -> Seq Scan on _hyper_3_8_chunk (15 rows) -- test INNER JOIN against non-hypertable @@ -928,18 +387,18 @@ LIMIT 2; -> Nested Loop -> Custom Scan (ChunkAppend) on dimension_only Order: dimension_only."time" DESC - -> Index Only Scan using _hyper_4_14_chunk_dimension_only_time_idx on _hyper_4_14_chunk - -> Index Only Scan using _hyper_4_13_chunk_dimension_only_time_idx on _hyper_4_13_chunk - -> Index Only Scan using _hyper_4_12_chunk_dimension_only_time_idx on _hyper_4_12_chunk - -> Index Only Scan using _hyper_4_11_chunk_dimension_only_time_idx on _hyper_4_11_chunk + -> Index Only Scan using _hyper_3_11_chunk_dimension_only_time_idx on _hyper_3_11_chunk + -> Index Only Scan using _hyper_3_10_chunk_dimension_only_time_idx on _hyper_3_10_chunk + -> Index Only Scan using _hyper_3_9_chunk_dimension_only_time_idx on _hyper_3_9_chunk + -> Index Only Scan using _hyper_3_8_chunk_dimension_only_time_idx on _hyper_3_8_chunk -> Append - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk Index Cond: ("time" = dimension_only."time") (17 rows) @@ -949,17 +408,17 @@ FROM dimension_last INNER JOIN devices USING(device_id) ORDER BY dimension_last.time DESC LIMIT 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- Limit (actual rows=2 loops=1) -> Nested Loop (actual rows=2 loops=1) Join Filter: (dimension_last.device_id = devices.device_id) -> Custom Scan (ChunkAppend) on dimension_last (actual rows=2 loops=1) Order: dimension_last."time" DESC - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk (actual rows=2 loops=1) - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk (never executed) - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk (never executed) - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk (never executed) + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk (actual rows=2 loops=1) + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk (never executed) + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk (never executed) + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk (never executed) -> Materialize (actual rows=1 loops=2) -> Seq Scan on devices (actual rows=1 loops=1) (11 rows) @@ -974,11 +433,11 @@ ORDER BY time ASC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ht_missing_indexes (actual rows=1 loops=1) Order: ht_missing_indexes."time" - -> Index Scan Backward using _hyper_5_15_chunk_ht_missing_indexes_time_idx on _hyper_5_15_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_4_12_chunk_ht_missing_indexes_time_idx on _hyper_4_12_chunk (actual rows=1 loops=1) -> Sort (never executed) - Sort Key: _hyper_5_16_chunk."time" - -> Seq Scan on _hyper_5_16_chunk (never executed) - -> Index Scan Backward using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk (never executed) + Sort Key: _hyper_4_13_chunk."time" + -> Seq Scan on _hyper_4_13_chunk (never executed) + -> Index Scan Backward using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk (never executed) (8 rows) -- test hypertable with index missing on one chunk @@ -993,14 +452,14 @@ ORDER BY time DESC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ht_missing_indexes (actual rows=1 loops=1) Order: ht_missing_indexes."time" DESC - -> Index Scan using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk (actual rows=1 loops=1) Filter: (device_id = 2) Rows Removed by Filter: 1 -> Sort (never executed) - Sort Key: _hyper_5_16_chunk."time" DESC - -> Seq Scan on _hyper_5_16_chunk (never executed) + Sort Key: _hyper_4_13_chunk."time" DESC + -> Seq Scan on _hyper_4_13_chunk (never executed) Filter: (device_id = 2) - -> Index Scan using _hyper_5_15_chunk_ht_missing_indexes_time_idx on _hyper_5_15_chunk (never executed) + -> Index Scan using _hyper_4_12_chunk_ht_missing_indexes_time_idx on _hyper_4_12_chunk (never executed) Filter: (device_id = 2) (12 rows) @@ -1017,12 +476,12 @@ ORDER BY time LIMIT 10; -> Custom Scan (ChunkAppend) on ht_missing_indexes (actual rows=10 loops=1) Order: ht_missing_indexes."time" -> Sort (actual rows=10 loops=1) - Sort Key: _hyper_5_16_chunk."time" + Sort Key: _hyper_4_13_chunk."time" Sort Method: top-N heapsort - -> Seq Scan on _hyper_5_16_chunk (actual rows=24477 loops=1) + -> Seq Scan on _hyper_4_13_chunk (actual rows=24477 loops=1) Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) Rows Removed by Filter: 5763 - -> Index Scan Backward using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk (never executed) + -> Index Scan Backward using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk (never executed) Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) (11 rows) @@ -1036,11 +495,11 @@ ORDER BY time ASC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ht_dropped_columns (actual rows=1 loops=1) Order: ht_dropped_columns."time" - -> Index Scan Backward using _hyper_6_18_chunk_ht_dropped_columns_time_idx on _hyper_6_18_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_6_19_chunk_ht_dropped_columns_time_idx on _hyper_6_19_chunk (never executed) - -> Index Scan Backward using _hyper_6_20_chunk_ht_dropped_columns_time_idx on _hyper_6_20_chunk (never executed) - -> Index Scan Backward using _hyper_6_21_chunk_ht_dropped_columns_time_idx on _hyper_6_21_chunk (never executed) - -> Index Scan Backward using _hyper_6_22_chunk_ht_dropped_columns_time_idx on _hyper_6_22_chunk (never executed) + -> Index Scan Backward using _hyper_5_15_chunk_ht_dropped_columns_time_idx on _hyper_5_15_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_5_16_chunk_ht_dropped_columns_time_idx on _hyper_5_16_chunk (never executed) + -> Index Scan Backward using _hyper_5_17_chunk_ht_dropped_columns_time_idx on _hyper_5_17_chunk (never executed) + -> Index Scan Backward using _hyper_5_18_chunk_ht_dropped_columns_time_idx on _hyper_5_18_chunk (never executed) + -> Index Scan Backward using _hyper_5_19_chunk_ht_dropped_columns_time_idx on _hyper_5_19_chunk (never executed) (8 rows) -- test hypertable with dropped columns @@ -1053,154 +512,18 @@ ORDER BY time DESC; ---------------------------------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on ht_dropped_columns (actual rows=7205 loops=1) Order: ht_dropped_columns."time" DESC - -> Index Scan using _hyper_6_22_chunk_ht_dropped_columns_time_idx on _hyper_6_22_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_19_chunk_ht_dropped_columns_time_idx on _hyper_5_19_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_21_chunk_ht_dropped_columns_time_idx on _hyper_6_21_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_18_chunk_ht_dropped_columns_time_idx on _hyper_5_18_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_20_chunk_ht_dropped_columns_time_idx on _hyper_6_20_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_17_chunk_ht_dropped_columns_time_idx on _hyper_5_17_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_19_chunk_ht_dropped_columns_time_idx on _hyper_6_19_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_16_chunk_ht_dropped_columns_time_idx on _hyper_5_16_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_18_chunk_ht_dropped_columns_time_idx on _hyper_6_18_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_15_chunk_ht_dropped_columns_time_idx on _hyper_5_15_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) (12 rows) --- test hypertable with space partitioning -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=77766 loops=1) - Order: space."time" - -> Merge Append (actual rows=40320 loops=1) - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=13440 loops=1) - -> Merge Append (actual rows=37446 loops=1) - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=12482 loops=1) -(14 rows) - --- test hypertable with space partitioning and exclusion in space --- should remove 3 of 4 space partitions (2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id = 1 -ORDER BY time; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=12961 loops=1) - Order: space."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - Filter: (device_id = 1) - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - Filter: (device_id = 1) -(6 rows) - --- test hypertable with space partitioning and exclusion in space --- should remove 2 of 4 space partitions (2 + 2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id IN (1, 4) -ORDER BY time; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=25922 loops=1) - Order: space."time" - -> Merge Append (actual rows=13440 loops=1) - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=6720 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - Rows Removed by Filter: 6720 - -> Merge Append (actual rows=12482 loops=1) - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=6241 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - Rows Removed by Filter: 6241 -(16 rows) - --- test hypertable with space partitioning and reverse order -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time DESC; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=77766 loops=1) - Order: space."time" DESC - -> Merge Append (actual rows=37446 loops=1) - Sort Key: _hyper_7_29_chunk."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=12482 loops=1) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Merge Append (actual rows=40320 loops=1) - Sort Key: _hyper_7_30_chunk."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=13440 loops=1) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) -(14 rows) - --- test hypertable with space partitioning ORDER BY multiple columns --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: _hyper_7_24_chunk."time", _hyper_7_24_chunk.device_id - Sort Method: top-N heapsort - -> Append (actual rows=77766 loops=1) - -> Seq Scan on _hyper_7_24_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Seq Scan on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_30_chunk (actual rows=13440 loops=1) - -> Seq Scan on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Seq Scan on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_29_chunk (actual rows=12482 loops=1) -(13 rows) - --- test hypertable with space partitioning ORDER BY non-time column --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY device_id, time LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: _hyper_7_23_chunk.device_id, _hyper_7_23_chunk."time" - Sort Method: top-N heapsort - -> Append (actual rows=77766 loops=1) - -> Seq Scan on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_24_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Seq Scan on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Seq Scan on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_29_chunk (actual rows=12482 loops=1) - -> Seq Scan on _hyper_7_30_chunk (actual rows=13440 loops=1) -(13 rows) - -- test hypertable with 2 space dimensions :PREFIX SELECT time, device_id, value @@ -1211,27 +534,27 @@ ORDER BY time DESC; Custom Scan (ChunkAppend) on space2 (actual rows=116649 loops=1) Order: space2."time" DESC -> Merge Append (actual rows=56169 loops=1) - Sort Key: _hyper_8_47_chunk."time" DESC - -> Index Scan using _hyper_8_47_chunk_space2_time_idx on _hyper_8_47_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_45_chunk_space2_time_idx on _hyper_8_45_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_43_chunk_space2_time_idx on _hyper_8_43_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_41_chunk_space2_time_idx on _hyper_8_41_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_39_chunk_space2_time_idx on _hyper_8_39_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_37_chunk_space2_time_idx on _hyper_8_37_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_35_chunk_space2_time_idx on _hyper_8_35_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_33_chunk_space2_time_idx on _hyper_8_33_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_31_chunk_space2_time_idx on _hyper_8_31_chunk (actual rows=6241 loops=1) + Sort Key: _hyper_6_36_chunk."time" DESC + -> Index Scan using _hyper_6_36_chunk_space2_time_idx on _hyper_6_36_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_34_chunk_space2_time_idx on _hyper_6_34_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_32_chunk_space2_time_idx on _hyper_6_32_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_30_chunk_space2_time_idx on _hyper_6_30_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_28_chunk_space2_time_idx on _hyper_6_28_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_26_chunk_space2_time_idx on _hyper_6_26_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_24_chunk_space2_time_idx on _hyper_6_24_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_22_chunk_space2_time_idx on _hyper_6_22_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_20_chunk_space2_time_idx on _hyper_6_20_chunk (actual rows=6241 loops=1) -> Merge Append (actual rows=60480 loops=1) - Sort Key: _hyper_8_48_chunk."time" DESC - -> Index Scan using _hyper_8_48_chunk_space2_time_idx on _hyper_8_48_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_46_chunk_space2_time_idx on _hyper_8_46_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_44_chunk_space2_time_idx on _hyper_8_44_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_42_chunk_space2_time_idx on _hyper_8_42_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_40_chunk_space2_time_idx on _hyper_8_40_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_38_chunk_space2_time_idx on _hyper_8_38_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_36_chunk_space2_time_idx on _hyper_8_36_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_34_chunk_space2_time_idx on _hyper_8_34_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_32_chunk_space2_time_idx on _hyper_8_32_chunk (actual rows=6720 loops=1) + Sort Key: _hyper_6_37_chunk."time" DESC + -> Index Scan using _hyper_6_37_chunk_space2_time_idx on _hyper_6_37_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_35_chunk_space2_time_idx on _hyper_6_35_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_33_chunk_space2_time_idx on _hyper_6_33_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_31_chunk_space2_time_idx on _hyper_6_31_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_29_chunk_space2_time_idx on _hyper_6_29_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_27_chunk_space2_time_idx on _hyper_6_27_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_25_chunk_space2_time_idx on _hyper_6_25_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_23_chunk_space2_time_idx on _hyper_6_23_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_21_chunk_space2_time_idx on _hyper_6_21_chunk (actual rows=6720 loops=1) (24 rows) -- test hypertable with 3 space dimensions @@ -1244,829 +567,67 @@ ORDER BY time DESC; Custom Scan (ChunkAppend) on space3 (actual rows=103688 loops=1) Order: space3."time" DESC -> Merge Append (actual rows=49928 loops=1) - Sort Key: _hyper_9_63_chunk."time" DESC - -> Index Only Scan using _hyper_9_63_chunk_space3_time_idx on _hyper_9_63_chunk (actual rows=6241 loops=1) + Sort Key: _hyper_7_52_chunk."time" DESC + -> Index Only Scan using _hyper_7_52_chunk_space3_time_idx on _hyper_7_52_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_61_chunk_space3_time_idx on _hyper_9_61_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_50_chunk_space3_time_idx on _hyper_7_50_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_59_chunk_space3_time_idx on _hyper_9_59_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_48_chunk_space3_time_idx on _hyper_7_48_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_57_chunk_space3_time_idx on _hyper_9_57_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_46_chunk_space3_time_idx on _hyper_7_46_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_55_chunk_space3_time_idx on _hyper_9_55_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_44_chunk_space3_time_idx on _hyper_7_44_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_53_chunk_space3_time_idx on _hyper_9_53_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_42_chunk_space3_time_idx on _hyper_7_42_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_51_chunk_space3_time_idx on _hyper_9_51_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_40_chunk_space3_time_idx on _hyper_7_40_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_49_chunk_space3_time_idx on _hyper_9_49_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_38_chunk_space3_time_idx on _hyper_7_38_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 -> Merge Append (actual rows=53760 loops=1) - Sort Key: _hyper_9_64_chunk."time" DESC - -> Index Only Scan using _hyper_9_64_chunk_space3_time_idx on _hyper_9_64_chunk (actual rows=6720 loops=1) + Sort Key: _hyper_7_53_chunk."time" DESC + -> Index Only Scan using _hyper_7_53_chunk_space3_time_idx on _hyper_7_53_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_62_chunk_space3_time_idx on _hyper_9_62_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_51_chunk_space3_time_idx on _hyper_7_51_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_60_chunk_space3_time_idx on _hyper_9_60_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_49_chunk_space3_time_idx on _hyper_7_49_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_58_chunk_space3_time_idx on _hyper_9_58_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_47_chunk_space3_time_idx on _hyper_7_47_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_56_chunk_space3_time_idx on _hyper_9_56_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_45_chunk_space3_time_idx on _hyper_7_45_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_54_chunk_space3_time_idx on _hyper_9_54_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_43_chunk_space3_time_idx on _hyper_7_43_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_52_chunk_space3_time_idx on _hyper_9_52_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_41_chunk_space3_time_idx on _hyper_7_41_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_50_chunk_space3_time_idx on _hyper_9_50_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_39_chunk_space3_time_idx on _hyper_7_39_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 (38 rows) --- expressions in ORDER BY clause -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=10 loops=1) - -> Custom Scan (ChunkAppend) on space (actual rows=10 loops=1) - Order: time_bucket('@ 1 hour'::interval, space."time") - -> Merge Append (actual rows=10 loops=1) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_24_chunk."time")) - -> Index Only Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=10 loops=1) - Heap Fetches: 10 - -> Index Only Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Merge Append (never executed) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_23_chunk."time")) - -> Index Only Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (never executed) - Heap Fetches: 0 -(23 rows) - -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 DESC LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=10 loops=1) - -> Custom Scan (ChunkAppend) on space (actual rows=10 loops=1) - Order: time_bucket('@ 1 hour'::interval, space."time") DESC - -> Merge Append (actual rows=10 loops=1) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_29_chunk."time")) DESC - -> Index Only Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=3 loops=1) - Heap Fetches: 3 - -> Index Only Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=2 loops=1) - Heap Fetches: 2 - -> Index Only Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=6 loops=1) - Heap Fetches: 6 - -> Index Only Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=2 loops=1) - Heap Fetches: 2 - -> Merge Append (never executed) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_30_chunk."time")) DESC - -> Index Only Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (never executed) - Heap Fetches: 0 -(23 rows) - --- test LATERAL with correlated query --- only last chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=1 loops=3) - Order: o."time" DESC - Chunks excluded during startup: 0 - Chunks excluded during runtime: 2 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_1 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(13 rows) - --- test LATERAL with correlated query --- only 2nd chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 -) l ON true; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Nested Loop Left Join (actual rows=2 loops=1) - -> Function Scan on generate_series g (actual rows=2 loops=1) - -> Limit (actual rows=1 loops=2) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=1 loops=2) - Order: o."time" - Chunks excluded during startup: 0 - Chunks excluded during runtime: 2 - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_1 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 (actual rows=1 loops=2) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_3 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(13 rows) - --- test startup and runtime exclusion together -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=1 loops=3) - Order: o."time" DESC - Chunks excluded during startup: 0 - Chunks excluded during runtime: 2 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_1 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) -(13 rows) - --- test startup and runtime exclusion together --- all chunks should be filtered -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=0 loops=3) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=0 loops=3) - Order: o."time" DESC - Chunks excluded during startup: 3 -(6 rows) - --- test CTE --- no chunk exclusion for CTE because cte query is not pulled up -:PREFIX WITH cte AS (SELECT * FROM ordered_append ORDER BY time) -SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - CTE Scan on cte (actual rows=73443 loops=1) - Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - CTE cte - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=73443 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=20160 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=30240 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=23043 loops=1) -(8 rows) - --- test JOIN --- no exclusion on joined table because quals are not propagated yet -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN ordered_append o2 ON o1.time = o2.time -WHERE o1.time < '2000-02-01' -ORDER BY o1.time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- - Merge Join (actual rows=220329 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=73443 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20160 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (actual rows=30240 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (actual rows=23043 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Materialize (actual rows=220327 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=73443 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=20160 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (actual rows=30240 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (actual rows=23043 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) -(19 rows) - --- test JOIN --- last chunk of o2 should not be executed -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN (SELECT * FROM ordered_append o2 ORDER BY time) o2 ON o1.time = o2.time -WHERE o1.time < '2000-01-08' -ORDER BY o1.time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- - Merge Join (actual rows=90720 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=30240 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20160 loops=1) - Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (actual rows=10080 loops=1) - Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) - -> Materialize (actual rows=90721 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=30241 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=20160 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (actual rows=10081 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test subquery --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append WHERE time = (SELECT max(time) FROM ordered_append) ORDER BY time; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------ - Custom Scan (ChunkAppend) on ordered_append (actual rows=3 loops=1) - Chunks excluded during runtime: 2 - InitPlan 2 (returns $1) - -> Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append ordered_append_1 (actual rows=1 loops=1) - Order: ordered_append_1."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk _hyper_1_3_chunk_1 (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk _hyper_1_2_chunk_1 (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk _hyper_1_1_chunk_1 (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" = $1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" = $1) - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=3 loops=1) - Index Cond: ("time" = $1) -(23 rows) - --- test join against max query --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append o1 INNER JOIN (SELECT max(time) AS max_time FROM ordered_append) o2 ON o1.time = o2.max_time ORDER BY time; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Sort (actual rows=3 loops=1) - Sort Key: o1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=3 loops=1) - -> Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Append (actual rows=3 loops=1) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1 (actual rows=0 loops=1) - Index Cond: ("time" = ($0)) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ("time" = ($0)) - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_2 (actual rows=3 loops=1) - Index Cond: ("time" = ($0)) -(25 rows) - --- test ordered append with limit expression -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT (SELECT length('four')); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=4 loops=1) - InitPlan 1 (returns $0) - -> Result (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=4 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=4 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(8 rows) - --- test with ordered guc disabled -SET timescaledb.enable_ordered_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Merge Append (actual rows=3 loops=1) - Sort Key: _hyper_1_1_chunk."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) -(6 rows) - -RESET timescaledb.enable_ordered_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=3 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test with chunk append disabled -SET timescaledb.enable_chunk_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Merge Append (actual rows=3 loops=1) - Sort Key: _hyper_1_1_chunk."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) -(6 rows) - -RESET timescaledb.enable_chunk_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=3 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test space partitioning with startup exclusion -:PREFIX SELECT * -FROM space WHERE time < now() ORDER BY time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=77766 loops=1) - Order: space."time" - -> Merge Append (actual rows=40320 loops=1) - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=13440 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=6720 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=13440 loops=1) - Index Cond: ("time" < now()) - -> Merge Append (actual rows=37446 loops=1) - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=12482 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=6241 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=12482 loops=1) - Index Cond: ("time" < now()) -(22 rows) - --- test runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on space o (actual rows=1 loops=3) - Order: o."time" DESC - -> Merge Append (actual rows=0 loops=3) - Sort Key: o_1."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk o_1 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk o_2 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk o_3 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk o_4 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Merge Append (actual rows=1 loops=3) - Sort Key: o_5."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk o_5 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk o_6 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk o_7 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk o_8 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(25 rows) - --- test startup and runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on space o (actual rows=1 loops=3) - Order: o."time" DESC - -> Merge Append (actual rows=0 loops=3) - Sort Key: o_1."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk o_1 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk o_2 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk o_3 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk o_4 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Merge Append (actual rows=1 loops=3) - Sort Key: o_5."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk o_5 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk o_6 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk o_7 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk o_8 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) -(25 rows) - --- test JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with USING --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 USING(time) ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test NATURAL JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 NATURAL INNER JOIN ordered_append o2 ORDER BY o1.time LIMIT 100; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - Join Filter: ((o1.device_id = o2.device_id) AND (o1.value = o2.value)) - Rows Removed by Join Filter: 198 - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=100 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=298 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=100 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(16 rows) - --- test LEFT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 LEFT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Left Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test RIGHT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 RIGHT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Left Join (actual rows=100 loops=1) - Merge Cond: (o2."time" = o1."time") - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) -(14 rows) - --- test JOIN on time column with ON clause expression order switched --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with equality condition in WHERE clause --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with ORDER BY 2nd hypertable --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column and device_id --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - Join Filter: (o1.device_id = o2.device_id) - Rows Removed by Join Filter: 198 - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=100 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=298 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=100 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(16 rows) - --- test JOIN on device_id --- should not use ordered append for 2nd hypertable -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Nested Loop (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=1 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Append (actual rows=100 loops=1) - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk o2 (actual rows=100 loops=1) - Index Cond: (device_id = o1.device_id) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk o2_1 (never executed) - Index Cond: (device_id = o1.device_id) - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk o2_2 (never executed) - Index Cond: (device_id = o1.device_id) -(14 rows) - --- test JOIN on time column with implicit join --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1, ordered_append o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with 3 hypertables --- should use 3 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time INNER JOIN ordered_append o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o3."time" = o1."time") - -> Custom Scan (ChunkAppend) on ordered_append o3 (actual rows=12 loops=1) - Order: o3."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o3_1 (actual rows=12 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o3_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o3_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Merge Join (actual rows=37 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=13 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=13 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=37 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=13 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=13 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(22 rows) - --- test with space partitioning -:PREFIX SELECT * FROM space s1 INNER JOIN space s2 ON s1.time = s2.time ORDER BY s1.time LIMIT 100; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (s1."time" = s2."time") - -> Custom Scan (ChunkAppend) on space s1 (actual rows=17 loops=1) - Order: s1."time" - -> Merge Append (actual rows=17 loops=1) - Sort Key: s1_1."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk s1_1 (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk s1_2 (actual rows=7 loops=1) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk s1_3 (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk s1_4 (actual rows=7 loops=1) - -> Merge Append (never executed) - Sort Key: s1_5."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk s1_5 (never executed) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk s1_6 (never executed) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk s1_7 (never executed) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk s1_8 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on space s2 (actual rows=19 loops=1) - Order: s2."time" - -> Merge Append (actual rows=19 loops=1) - Sort Key: s2_1."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk s2_1 (actual rows=4 loops=1) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk s2_2 (actual rows=7 loops=1) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk s2_3 (actual rows=4 loops=1) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk s2_4 (actual rows=7 loops=1) - -> Merge Append (never executed) - Sort Key: s2_5."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk s2_5 (never executed) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk s2_6 (never executed) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk s2_7 (never executed) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk s2_8 (never executed) -(32 rows) - -- test COLLATION -- cant be tested in our ci because alpine doesnt support locales -- :PREFIX SELECT * FROM sortopt_test ORDER BY time, device COLLATE "en_US.utf8"; -- test NULLS FIRST :PREFIX SELECT * FROM sortopt_test ORDER BY time, device NULLS FIRST; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on sortopt_test (actual rows=12961 loops=1) Order: sortopt_test."time", sortopt_test.device NULLS FIRST - -> Index Only Scan using _hyper_10_66_chunk_time_device_nullsfirst on _hyper_10_66_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_8_55_chunk_time_device_nullsfirst on _hyper_8_55_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_10_65_chunk_time_device_nullsfirst on _hyper_10_65_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_8_54_chunk_time_device_nullsfirst on _hyper_8_54_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 (6 rows) -- test NULLS LAST :PREFIX SELECT * FROM sortopt_test ORDER BY time, device DESC NULLS LAST; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on sortopt_test (actual rows=12961 loops=1) Order: sortopt_test."time", sortopt_test.device DESC NULLS LAST - -> Index Only Scan using _hyper_10_66_chunk_time_device_nullslast on _hyper_10_66_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_8_55_chunk_time_device_nullslast on _hyper_8_55_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_10_65_chunk_time_device_nullslast on _hyper_10_65_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_8_54_chunk_time_device_nullslast on _hyper_8_54_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 (6 rows) diff --git a/test/expected/plan_ordered_append-11.out b/test/expected/plan_ordered_append-11.out index 3eb802294..4fc27da66 100644 --- a/test/expected/plan_ordered_append-11.out +++ b/test/expected/plan_ordered_append-11.out @@ -42,25 +42,12 @@ INSERT INTO devices VALUES (1,'Device 1'), (2,'Device 2'), (3,'Device 3'); --- create a table where we create chunks in order -CREATE TABLE ordered_append(time timestamptz NOT NULL, device_id INT, value float); -SELECT create_hypertable('ordered_append','time'); - create_hypertable ------------------------------ - (1,public,ordered_append,t) -(1 row) - -CREATE index on ordered_append(time DESC,device_id); -CREATE index on ordered_append(device_id,time DESC); -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 1, 0.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 2, 1.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 3, 2.5; -- create a second table where we create chunks in reverse order CREATE TABLE ordered_append_reverse(time timestamptz NOT NULL, device_id INT, value float); SELECT create_hypertable('ordered_append_reverse','time'); create_hypertable ------------------------------------- - (2,public,ordered_append_reverse,t) + (1,public,ordered_append_reverse,t) (1 row) INSERT INTO ordered_append_reverse SELECT generate_series('2000-01-18'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 0.5; @@ -74,7 +61,7 @@ CREATE TABLE IF NOT EXISTS dimension_last( SELECT create_hypertable('dimension_last', 'time', chunk_time_interval => interval '1day', if_not_exists => True); create_hypertable ----------------------------- - (3,public,dimension_last,t) + (2,public,dimension_last,t) (1 row) -- table with only dimension column @@ -84,7 +71,7 @@ CREATE TABLE IF NOT EXISTS dimension_only( SELECT create_hypertable('dimension_only', 'time', chunk_time_interval => interval '1day', if_not_exists => True); create_hypertable ----------------------------- - (4,public,dimension_only,t) + (3,public,dimension_only,t) (1 row) INSERT INTO dimension_last SELECT 1,1,'Device 1',generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-04 23:59:00+0'::timestamptz,'1m'::interval); @@ -94,7 +81,6 @@ INSERT INTO dimension_only VALUES ('2000-01-05'), ('2000-01-07'); ANALYZE devices; -ANALYZE ordered_append; ANALYZE ordered_append_reverse; ANALYZE dimension_last; ANALYZE dimension_only; @@ -103,7 +89,7 @@ CREATE TABLE ht_missing_indexes(time timestamptz NOT NULL, device_id int, value SELECT create_hypertable('ht_missing_indexes','time'); create_hypertable --------------------------------- - (5,public,ht_missing_indexes,t) + (4,public,ht_missing_indexes,t) (1 row) INSERT INTO ht_missing_indexes SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 1, 0.5; @@ -123,7 +109,7 @@ CREATE TABLE ht_dropped_columns(c1 int, c2 int, c3 int, c4 int, c5 int, time tim SELECT create_hypertable('ht_dropped_columns','time'); create_hypertable --------------------------------- - (6,public,ht_dropped_columns,t) + (5,public,ht_dropped_columns,t) (1 row) ALTER TABLE ht_dropped_columns DROP COLUMN c1; @@ -137,31 +123,17 @@ INSERT INTO ht_dropped_columns(time,device_id,value) SELECT generate_series('200 ALTER TABLE ht_dropped_columns DROP COLUMN c5; INSERT INTO ht_dropped_columns(time,device_id,value) SELECT generate_series('2000-01-29'::timestamptz,'2000-01-30'::timestamptz,'1m'::interval), 1, 0.5; ANALYZE ht_dropped_columns; -CREATE TABLE space(time timestamptz NOT NULL, device_id int NOT NULL, value float); -SELECT create_hypertable('space','time','device_id',number_partitions:=4); - create_hypertable --------------------- - (7,public,space,t) -(1 row) - -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 2, 2.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 3, 3.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 4, 4.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 5, 5.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 6, 6.5; -ANALYZE space; CREATE TABLE space2(time timestamptz NOT NULL, device_id int NOT NULL, tag_id int NOT NULL, value float); SELECT create_hypertable('space2','time','device_id',number_partitions:=3); create_hypertable --------------------- - (8,public,space2,t) + (6,public,space2,t) (1 row) SELECT add_dimension('space2','tag_id',number_partitions:=3); - add_dimension ------------------------------ - (11,public,space2,tag_id,t) + add_dimension +---------------------------- + (8,public,space2,tag_id,t) (1 row) INSERT INTO space2 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1, 1.5; @@ -178,19 +150,19 @@ CREATE TABLE space3(time timestamptz NOT NULL, x int NOT NULL, y int NOT NULL, z SELECT create_hypertable('space3','time','x',number_partitions:=2); create_hypertable --------------------- - (9,public,space3,t) + (7,public,space3,t) (1 row) SELECT add_dimension('space3','y',number_partitions:=2); add_dimension ------------------------ - (14,public,space3,y,t) + (11,public,space3,y,t) (1 row) SELECT add_dimension('space3','z',number_partitions:=2); add_dimension ------------------------ - (15,public,space3,z,t) + (12,public,space3,z,t) (1 row) INSERT INTO space3 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1, 1, 1.5; @@ -204,9 +176,9 @@ INSERT INTO space3 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01' ANALYZE space3; CREATE TABLE sortopt_test(time timestamptz NOT NULL, device TEXT); SELECT create_hypertable('sortopt_test','time',create_default_indexes:=false); - create_hypertable ----------------------------- - (10,public,sortopt_test,t) + create_hypertable +--------------------------- + (8,public,sortopt_test,t) (1 row) -- since alpine does not support locales we cant test collations in our ci @@ -232,105 +204,64 @@ FROM INNER JOIN _timescaledb_catalog.dimension d ON ds.dimension_id = d.id INNER JOIN _timescaledb_catalog.hypertable ht ON d.hypertable_id = ht.id ORDER BY ht.table_name, range_start, chunk; - hypertable | chunk | range_start -------------------------+--------------------+---------------------- - dimension_last | _hyper_3_7_chunk | 946684800000000 - dimension_last | _hyper_3_8_chunk | 946771200000000 - dimension_last | _hyper_3_9_chunk | 946857600000000 - dimension_last | _hyper_3_10_chunk | 946944000000000 - dimension_only | _hyper_4_11_chunk | 946684800000000 - dimension_only | _hyper_4_12_chunk | 946857600000000 - dimension_only | _hyper_4_13_chunk | 947030400000000 - dimension_only | _hyper_4_14_chunk | 947203200000000 - ht_dropped_columns | _hyper_6_18_chunk | 946512000000000 - ht_dropped_columns | _hyper_6_19_chunk | 947116800000000 - ht_dropped_columns | _hyper_6_20_chunk | 947721600000000 - ht_dropped_columns | _hyper_6_21_chunk | 948326400000000 - ht_dropped_columns | _hyper_6_22_chunk | 948931200000000 - ht_missing_indexes | _hyper_5_15_chunk | 946512000000000 - ht_missing_indexes | _hyper_5_16_chunk | 947116800000000 - ht_missing_indexes | _hyper_5_17_chunk | 947721600000000 - ordered_append | _hyper_1_1_chunk | 946512000000000 - ordered_append | _hyper_1_2_chunk | 947116800000000 - ordered_append | _hyper_1_3_chunk | 947721600000000 - ordered_append_reverse | _hyper_2_6_chunk | 946512000000000 - ordered_append_reverse | _hyper_2_5_chunk | 947116800000000 - ordered_append_reverse | _hyper_2_4_chunk | 947721600000000 - sortopt_test | _hyper_10_66_chunk | 946512000000000 - sortopt_test | _hyper_10_65_chunk | 947116800000000 - space | _hyper_7_24_chunk | -9223372036854775808 - space | _hyper_7_26_chunk | 946512000000000 - space | _hyper_7_28_chunk | 946512000000000 - space | _hyper_7_30_chunk | 946512000000000 - space | _hyper_7_23_chunk | 947116800000000 - space | _hyper_7_25_chunk | 947116800000000 - space | _hyper_7_27_chunk | 947116800000000 - space | _hyper_7_29_chunk | 947116800000000 - space2 | _hyper_8_32_chunk | -9223372036854775808 - space2 | _hyper_8_34_chunk | -9223372036854775808 - space2 | _hyper_8_36_chunk | -9223372036854775808 - space2 | _hyper_8_38_chunk | -9223372036854775808 - space2 | _hyper_8_44_chunk | -9223372036854775808 - space2 | _hyper_8_40_chunk | 946512000000000 - space2 | _hyper_8_42_chunk | 946512000000000 - space2 | _hyper_8_46_chunk | 946512000000000 - space2 | _hyper_8_48_chunk | 946512000000000 - space2 | _hyper_8_31_chunk | 947116800000000 - space2 | _hyper_8_33_chunk | 947116800000000 - space2 | _hyper_8_35_chunk | 947116800000000 - space2 | _hyper_8_37_chunk | 947116800000000 - space2 | _hyper_8_39_chunk | 947116800000000 - space2 | _hyper_8_41_chunk | 947116800000000 - space2 | _hyper_8_43_chunk | 947116800000000 - space2 | _hyper_8_45_chunk | 947116800000000 - space2 | _hyper_8_47_chunk | 947116800000000 - space3 | _hyper_9_50_chunk | -9223372036854775808 - space3 | _hyper_9_52_chunk | -9223372036854775808 - space3 | _hyper_9_54_chunk | -9223372036854775808 - space3 | _hyper_9_56_chunk | -9223372036854775808 - space3 | _hyper_9_58_chunk | -9223372036854775808 - space3 | _hyper_9_60_chunk | -9223372036854775808 - space3 | _hyper_9_62_chunk | -9223372036854775808 - space3 | _hyper_9_64_chunk | 946512000000000 - space3 | _hyper_9_49_chunk | 947116800000000 - space3 | _hyper_9_51_chunk | 947116800000000 - space3 | _hyper_9_53_chunk | 947116800000000 - space3 | _hyper_9_55_chunk | 947116800000000 - space3 | _hyper_9_57_chunk | 947116800000000 - space3 | _hyper_9_59_chunk | 947116800000000 - space3 | _hyper_9_61_chunk | 947116800000000 - space3 | _hyper_9_63_chunk | 947116800000000 -(66 rows) - --- test ASC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test DESC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) -(6 rows) + hypertable | chunk | range_start +------------------------+-------------------+---------------------- + dimension_last | _hyper_2_4_chunk | 946684800000000 + dimension_last | _hyper_2_5_chunk | 946771200000000 + dimension_last | _hyper_2_6_chunk | 946857600000000 + dimension_last | _hyper_2_7_chunk | 946944000000000 + dimension_only | _hyper_3_8_chunk | 946684800000000 + dimension_only | _hyper_3_9_chunk | 946857600000000 + dimension_only | _hyper_3_10_chunk | 947030400000000 + dimension_only | _hyper_3_11_chunk | 947203200000000 + ht_dropped_columns | _hyper_5_15_chunk | 946512000000000 + ht_dropped_columns | _hyper_5_16_chunk | 947116800000000 + ht_dropped_columns | _hyper_5_17_chunk | 947721600000000 + ht_dropped_columns | _hyper_5_18_chunk | 948326400000000 + ht_dropped_columns | _hyper_5_19_chunk | 948931200000000 + ht_missing_indexes | _hyper_4_12_chunk | 946512000000000 + ht_missing_indexes | _hyper_4_13_chunk | 947116800000000 + ht_missing_indexes | _hyper_4_14_chunk | 947721600000000 + ordered_append_reverse | _hyper_1_3_chunk | 946512000000000 + ordered_append_reverse | _hyper_1_2_chunk | 947116800000000 + ordered_append_reverse | _hyper_1_1_chunk | 947721600000000 + sortopt_test | _hyper_8_55_chunk | 946512000000000 + sortopt_test | _hyper_8_54_chunk | 947116800000000 + space2 | _hyper_6_21_chunk | -9223372036854775808 + space2 | _hyper_6_23_chunk | -9223372036854775808 + space2 | _hyper_6_25_chunk | -9223372036854775808 + space2 | _hyper_6_27_chunk | -9223372036854775808 + space2 | _hyper_6_33_chunk | -9223372036854775808 + space2 | _hyper_6_29_chunk | 946512000000000 + space2 | _hyper_6_31_chunk | 946512000000000 + space2 | _hyper_6_35_chunk | 946512000000000 + space2 | _hyper_6_37_chunk | 946512000000000 + space2 | _hyper_6_20_chunk | 947116800000000 + space2 | _hyper_6_22_chunk | 947116800000000 + space2 | _hyper_6_24_chunk | 947116800000000 + space2 | _hyper_6_26_chunk | 947116800000000 + space2 | _hyper_6_28_chunk | 947116800000000 + space2 | _hyper_6_30_chunk | 947116800000000 + space2 | _hyper_6_32_chunk | 947116800000000 + space2 | _hyper_6_34_chunk | 947116800000000 + space2 | _hyper_6_36_chunk | 947116800000000 + space3 | _hyper_7_39_chunk | -9223372036854775808 + space3 | _hyper_7_41_chunk | -9223372036854775808 + space3 | _hyper_7_43_chunk | -9223372036854775808 + space3 | _hyper_7_45_chunk | -9223372036854775808 + space3 | _hyper_7_47_chunk | -9223372036854775808 + space3 | _hyper_7_49_chunk | -9223372036854775808 + space3 | _hyper_7_51_chunk | -9223372036854775808 + space3 | _hyper_7_53_chunk | 946512000000000 + space3 | _hyper_7_38_chunk | 947116800000000 + space3 | _hyper_7_40_chunk | 947116800000000 + space3 | _hyper_7_42_chunk | 947116800000000 + space3 | _hyper_7_44_chunk | 947116800000000 + space3 | _hyper_7_46_chunk | 947116800000000 + space3 | _hyper_7_48_chunk | 947116800000000 + space3 | _hyper_7_50_chunk | 947116800000000 + space3 | _hyper_7_52_chunk | 947116800000000 +(55 rows) -- test ASC for reverse ordered chunks :PREFIX SELECT @@ -342,9 +273,9 @@ ORDER BY time ASC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ordered_append_reverse (actual rows=1 loops=1) Order: ordered_append_reverse."time" - -> Index Scan Backward using _hyper_2_6_chunk_ordered_append_reverse_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_2_5_chunk_ordered_append_reverse_time_idx on _hyper_2_5_chunk (never executed) - -> Index Scan Backward using _hyper_2_4_chunk_ordered_append_reverse_time_idx on _hyper_2_4_chunk (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_reverse_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_reverse_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_reverse_time_idx on _hyper_1_1_chunk (never executed) (6 rows) -- test DESC for reverse ordered chunks @@ -357,356 +288,9 @@ ORDER BY time DESC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ordered_append_reverse (actual rows=1 loops=1) Order: ordered_append_reverse."time" DESC - -> Index Scan using _hyper_2_4_chunk_ordered_append_reverse_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_2_5_chunk_ordered_append_reverse_time_idx on _hyper_2_5_chunk (never executed) - -> Index Scan using _hyper_2_6_chunk_ordered_append_reverse_time_idx on _hyper_2_6_chunk (never executed) -(6 rows) - --- test query with ORDER BY column not in targetlist -:PREFIX SELECT - device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- ORDER BY may include other columns after time column -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC, ordered_append.device_id - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_device_id_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_device_id_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_device_id_idx on _hyper_1_1_chunk (never executed) -(6 rows) - --- test RECORD in targetlist -:PREFIX SELECT - (time, device_id, value) -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC, ordered_append.device_id - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_device_id_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_device_id_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_device_id_idx on _hyper_1_1_chunk (never executed) -(6 rows) - --- test sort column not in targetlist -:PREFIX SELECT - time_bucket('1h',time) -FROM ordered_append -ORDER BY time DESC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Heap Fetches: 0 -(9 rows) - --- queries with ORDER BY non-time column shouldn't use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Merge Append (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) -(6 rows) - --- time column must be primary sort order -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id, time LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk.device_id, _hyper_1_1_chunk."time" - Sort Method: top-N heapsort - -> Append (actual rows=73443 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=20160 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=30240 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=23043 loops=1) -(8 rows) - --- queries without LIMIT should use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on ordered_append (actual rows=73443 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=20160 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=30240 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=23043 loops=1) -(5 rows) - --- queries without ORDER BY shouldnt use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -LIMIT 1; - QUERY PLAN ------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Append (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_2_chunk (never executed) - -> Seq Scan on _hyper_1_3_chunk (never executed) -(5 rows) - --- test interaction with constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) -(7 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) -(7 rows) - --- test interaction with constraint aware append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" > now_s()) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) - Index Cond: ("time" > now_s()) -(8 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" < now_s()) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" < now_s()) -(8 rows) - --- test constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() AND time < '2000-01-10' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: (("time" > now_s()) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) -(6 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() AND time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: (("time" < now_s()) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) -(6 rows) - --- min/max queries -:PREFIX SELECT max(time) FROM ordered_append; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------- - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 -(14 rows) - -:PREFIX SELECT min(time) FROM ordered_append; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Only Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 -(14 rows) - --- test first/last (doesn't use ordered append yet) -:PREFIX SELECT first(time, time) FROM ordered_append; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Result (actual rows=1 loops=1) - -> Merge Append (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk."time" - -> Index Only Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 -(15 rows) - -:PREFIX SELECT last(time, time) FROM ordered_append; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Result (actual rows=1 loops=1) - -> Merge Append (actual rows=1 loops=1) - Sort Key: _hyper_1_1_chunk."time" DESC - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 -(15 rows) - --- test query with time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: time_bucket('@ 1 day'::interval, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time_bucket('1d',time) LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: time_bucket('@ 1 day'::interval, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) + -> Index Scan using _hyper_1_1_chunk_ordered_append_reverse_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_1_2_chunk_ordered_append_reverse_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan using _hyper_1_3_chunk_ordered_append_reverse_time_idx on _hyper_1_3_chunk (never executed) (6 rows) -- test query with ORDER BY time_bucket, device_id @@ -719,46 +303,16 @@ ORDER BY time_bucket('1d',time), device_id LIMIT 1; ----------------------------------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) -> Sort (actual rows=1 loops=1) - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_3_7_chunk."time")), _hyper_3_7_chunk.device_id + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id Sort Method: top-N heapsort -> Result (actual rows=5760 loops=1) -> Append (actual rows=5760 loops=1) - -> Seq Scan on _hyper_3_7_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_8_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_9_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_10_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=1440 loops=1) (10 rows) --- test query with ORDER BY date_trunc -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY date_trunc('day', time) LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: date_trunc('day'::text, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test query with ORDER BY date_trunc -:PREFIX SELECT - date_trunc('day',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: date_trunc('day'::text, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - -- test query with ORDER BY date_trunc, device_id -- must not use ordered append :PREFIX SELECT @@ -769,111 +323,16 @@ ORDER BY 1,2 LIMIT 1; -------------------------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) -> Sort (actual rows=1 loops=1) - Sort Key: (date_trunc('day'::text, _hyper_3_7_chunk."time")), _hyper_3_7_chunk.device_id + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id Sort Method: top-N heapsort -> Result (actual rows=5760 loops=1) -> Append (actual rows=5760 loops=1) - -> Seq Scan on _hyper_3_7_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_8_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_9_chunk (actual rows=1440 loops=1) - -> Seq Scan on _hyper_3_10_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=1440 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=1440 loops=1) (10 rows) --- test query with now() should result in ordered ChunkAppend -:PREFIX SELECT * FROM ordered_append WHERE time < now() + '1 month' -ORDER BY time DESC limit 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) -(10 rows) - --- test CTE -:PREFIX WITH i AS (SELECT * FROM ordered_append WHERE time < now() ORDER BY time DESC limit 100) -SELECT * FROM i; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - CTE Scan on i (actual rows=100 loops=1) - CTE i - -> Limit (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=100 loops=1) - Order: ordered_append."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=100 loops=1) - Index Cond: ("time" < now()) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" < now()) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" < now()) -(12 rows) - --- test LATERAL with ordered append in the outer query -:PREFIX SELECT * FROM ordered_append, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=2 loops=1) - -> Nested Loop (actual rows=2 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - -> Materialize (actual rows=2 loops=1) - -> Values Scan on "*VALUES*" (actual rows=2 loops=1) -(9 rows) - --- test LATERAL with ordered append in the lateral query -:PREFIX SELECT * FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM ordered_append ORDER BY time DESC limit 2) l; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- - Nested Loop (actual rows=4 loops=1) - -> Values Scan on "*VALUES*" (actual rows=2 loops=1) - -> Materialize (actual rows=2 loops=2) - -> Limit (actual rows=2 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=2 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=2 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) -(9 rows) - --- test plan with best index is chosen --- this should use device_id, time index -:PREFIX SELECT * FROM ordered_append WHERE device_id = 1 ORDER BY time DESC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: (device_id = 1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: (device_id = 1) - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: (device_id = 1) -(9 rows) - --- test plan with best index is chosen --- this should use time index -:PREFIX SELECT * FROM ordered_append ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) -(6 rows) - -- test with table with only dimension column :PREFIX SELECT * FROM dimension_only ORDER BY time DESC LIMIT 1; QUERY PLAN @@ -881,13 +340,13 @@ SELECT * FROM i; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on dimension_only (actual rows=1 loops=1) Order: dimension_only."time" DESC - -> Index Only Scan using _hyper_4_14_chunk_dimension_only_time_idx on _hyper_4_14_chunk (actual rows=1 loops=1) + -> Index Only Scan using _hyper_3_11_chunk_dimension_only_time_idx on _hyper_3_11_chunk (actual rows=1 loops=1) Heap Fetches: 1 - -> Index Only Scan using _hyper_4_13_chunk_dimension_only_time_idx on _hyper_4_13_chunk (never executed) + -> Index Only Scan using _hyper_3_10_chunk_dimension_only_time_idx on _hyper_3_10_chunk (never executed) Heap Fetches: 0 - -> Index Only Scan using _hyper_4_12_chunk_dimension_only_time_idx on _hyper_4_12_chunk (never executed) + -> Index Only Scan using _hyper_3_9_chunk_dimension_only_time_idx on _hyper_3_9_chunk (never executed) Heap Fetches: 0 - -> Index Only Scan using _hyper_4_11_chunk_dimension_only_time_idx on _hyper_4_11_chunk (never executed) + -> Index Only Scan using _hyper_3_8_chunk_dimension_only_time_idx on _hyper_3_8_chunk (never executed) Heap Fetches: 0 (11 rows) @@ -897,23 +356,23 @@ FROM dimension_last LEFT JOIN dimension_only USING (time) ORDER BY dimension_last.time DESC LIMIT 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Limit -> Nested Loop Left Join - Join Filter: (dimension_last."time" = _hyper_4_14_chunk."time") + Join Filter: (dimension_last."time" = _hyper_3_11_chunk."time") -> Custom Scan (ChunkAppend) on dimension_last Order: dimension_last."time" DESC - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk -> Materialize -> Append - -> Seq Scan on _hyper_4_14_chunk - -> Seq Scan on _hyper_4_13_chunk - -> Seq Scan on _hyper_4_12_chunk - -> Seq Scan on _hyper_4_11_chunk + -> Seq Scan on _hyper_3_11_chunk + -> Seq Scan on _hyper_3_10_chunk + -> Seq Scan on _hyper_3_9_chunk + -> Seq Scan on _hyper_3_8_chunk (15 rows) -- test INNER JOIN against non-hypertable @@ -928,18 +387,18 @@ LIMIT 2; -> Nested Loop -> Custom Scan (ChunkAppend) on dimension_only Order: dimension_only."time" DESC - -> Index Only Scan using _hyper_4_14_chunk_dimension_only_time_idx on _hyper_4_14_chunk - -> Index Only Scan using _hyper_4_13_chunk_dimension_only_time_idx on _hyper_4_13_chunk - -> Index Only Scan using _hyper_4_12_chunk_dimension_only_time_idx on _hyper_4_12_chunk - -> Index Only Scan using _hyper_4_11_chunk_dimension_only_time_idx on _hyper_4_11_chunk + -> Index Only Scan using _hyper_3_11_chunk_dimension_only_time_idx on _hyper_3_11_chunk + -> Index Only Scan using _hyper_3_10_chunk_dimension_only_time_idx on _hyper_3_10_chunk + -> Index Only Scan using _hyper_3_9_chunk_dimension_only_time_idx on _hyper_3_9_chunk + -> Index Only Scan using _hyper_3_8_chunk_dimension_only_time_idx on _hyper_3_8_chunk -> Append - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk Index Cond: ("time" = dimension_only."time") (17 rows) @@ -949,17 +408,17 @@ FROM dimension_last INNER JOIN devices USING(device_id) ORDER BY dimension_last.time DESC LIMIT 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- Limit (actual rows=2 loops=1) -> Nested Loop (actual rows=2 loops=1) Join Filter: (dimension_last.device_id = devices.device_id) -> Custom Scan (ChunkAppend) on dimension_last (actual rows=2 loops=1) Order: dimension_last."time" DESC - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk (actual rows=2 loops=1) - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk (never executed) - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk (never executed) - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk (never executed) + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk (actual rows=2 loops=1) + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk (never executed) + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk (never executed) + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk (never executed) -> Materialize (actual rows=1 loops=2) -> Seq Scan on devices (actual rows=1 loops=1) (11 rows) @@ -974,11 +433,11 @@ ORDER BY time ASC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ht_missing_indexes (actual rows=1 loops=1) Order: ht_missing_indexes."time" - -> Index Scan Backward using _hyper_5_15_chunk_ht_missing_indexes_time_idx on _hyper_5_15_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_4_12_chunk_ht_missing_indexes_time_idx on _hyper_4_12_chunk (actual rows=1 loops=1) -> Sort (never executed) - Sort Key: _hyper_5_16_chunk."time" - -> Seq Scan on _hyper_5_16_chunk (never executed) - -> Index Scan Backward using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk (never executed) + Sort Key: _hyper_4_13_chunk."time" + -> Seq Scan on _hyper_4_13_chunk (never executed) + -> Index Scan Backward using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk (never executed) (8 rows) -- test hypertable with index missing on one chunk @@ -993,14 +452,14 @@ ORDER BY time DESC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ht_missing_indexes (actual rows=1 loops=1) Order: ht_missing_indexes."time" DESC - -> Index Scan using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk (actual rows=1 loops=1) Filter: (device_id = 2) Rows Removed by Filter: 1 -> Sort (never executed) - Sort Key: _hyper_5_16_chunk."time" DESC - -> Seq Scan on _hyper_5_16_chunk (never executed) + Sort Key: _hyper_4_13_chunk."time" DESC + -> Seq Scan on _hyper_4_13_chunk (never executed) Filter: (device_id = 2) - -> Index Scan using _hyper_5_15_chunk_ht_missing_indexes_time_idx on _hyper_5_15_chunk (never executed) + -> Index Scan using _hyper_4_12_chunk_ht_missing_indexes_time_idx on _hyper_4_12_chunk (never executed) Filter: (device_id = 2) (12 rows) @@ -1017,12 +476,12 @@ ORDER BY time LIMIT 10; -> Custom Scan (ChunkAppend) on ht_missing_indexes (actual rows=10 loops=1) Order: ht_missing_indexes."time" -> Sort (actual rows=10 loops=1) - Sort Key: _hyper_5_16_chunk."time" + Sort Key: _hyper_4_13_chunk."time" Sort Method: top-N heapsort - -> Seq Scan on _hyper_5_16_chunk (actual rows=24477 loops=1) + -> Seq Scan on _hyper_4_13_chunk (actual rows=24477 loops=1) Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) Rows Removed by Filter: 5763 - -> Index Scan Backward using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk (never executed) + -> Index Scan Backward using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk (never executed) Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) (11 rows) @@ -1036,11 +495,11 @@ ORDER BY time ASC LIMIT 1; Limit (actual rows=1 loops=1) -> Custom Scan (ChunkAppend) on ht_dropped_columns (actual rows=1 loops=1) Order: ht_dropped_columns."time" - -> Index Scan Backward using _hyper_6_18_chunk_ht_dropped_columns_time_idx on _hyper_6_18_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_6_19_chunk_ht_dropped_columns_time_idx on _hyper_6_19_chunk (never executed) - -> Index Scan Backward using _hyper_6_20_chunk_ht_dropped_columns_time_idx on _hyper_6_20_chunk (never executed) - -> Index Scan Backward using _hyper_6_21_chunk_ht_dropped_columns_time_idx on _hyper_6_21_chunk (never executed) - -> Index Scan Backward using _hyper_6_22_chunk_ht_dropped_columns_time_idx on _hyper_6_22_chunk (never executed) + -> Index Scan Backward using _hyper_5_15_chunk_ht_dropped_columns_time_idx on _hyper_5_15_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_5_16_chunk_ht_dropped_columns_time_idx on _hyper_5_16_chunk (never executed) + -> Index Scan Backward using _hyper_5_17_chunk_ht_dropped_columns_time_idx on _hyper_5_17_chunk (never executed) + -> Index Scan Backward using _hyper_5_18_chunk_ht_dropped_columns_time_idx on _hyper_5_18_chunk (never executed) + -> Index Scan Backward using _hyper_5_19_chunk_ht_dropped_columns_time_idx on _hyper_5_19_chunk (never executed) (8 rows) -- test hypertable with dropped columns @@ -1053,154 +512,18 @@ ORDER BY time DESC; ---------------------------------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on ht_dropped_columns (actual rows=7205 loops=1) Order: ht_dropped_columns."time" DESC - -> Index Scan using _hyper_6_22_chunk_ht_dropped_columns_time_idx on _hyper_6_22_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_19_chunk_ht_dropped_columns_time_idx on _hyper_5_19_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_21_chunk_ht_dropped_columns_time_idx on _hyper_6_21_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_18_chunk_ht_dropped_columns_time_idx on _hyper_5_18_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_20_chunk_ht_dropped_columns_time_idx on _hyper_6_20_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_17_chunk_ht_dropped_columns_time_idx on _hyper_5_17_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_19_chunk_ht_dropped_columns_time_idx on _hyper_6_19_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_16_chunk_ht_dropped_columns_time_idx on _hyper_5_16_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) - -> Index Scan using _hyper_6_18_chunk_ht_dropped_columns_time_idx on _hyper_6_18_chunk (actual rows=1441 loops=1) + -> Index Scan using _hyper_5_15_chunk_ht_dropped_columns_time_idx on _hyper_5_15_chunk (actual rows=1441 loops=1) Filter: (device_id = 1) (12 rows) --- test hypertable with space partitioning -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=77766 loops=1) - Order: space."time" - -> Merge Append (actual rows=40320 loops=1) - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=13440 loops=1) - -> Merge Append (actual rows=37446 loops=1) - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=12482 loops=1) -(14 rows) - --- test hypertable with space partitioning and exclusion in space --- should remove 3 of 4 space partitions (2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id = 1 -ORDER BY time; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=12961 loops=1) - Order: space."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - Filter: (device_id = 1) - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - Filter: (device_id = 1) -(6 rows) - --- test hypertable with space partitioning and exclusion in space --- should remove 2 of 4 space partitions (2 + 2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id IN (1, 4) -ORDER BY time; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=25922 loops=1) - Order: space."time" - -> Merge Append (actual rows=13440 loops=1) - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=6720 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - Rows Removed by Filter: 6720 - -> Merge Append (actual rows=12482 loops=1) - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=6241 loops=1) - Filter: (device_id = ANY ('{1,4}'::integer[])) - Rows Removed by Filter: 6241 -(16 rows) - --- test hypertable with space partitioning and reverse order -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time DESC; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=77766 loops=1) - Order: space."time" DESC - -> Merge Append (actual rows=37446 loops=1) - Sort Key: _hyper_7_29_chunk."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=12482 loops=1) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Merge Append (actual rows=40320 loops=1) - Sort Key: _hyper_7_30_chunk."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=13440 loops=1) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) -(14 rows) - --- test hypertable with space partitioning ORDER BY multiple columns --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: _hyper_7_24_chunk."time", _hyper_7_24_chunk.device_id - Sort Method: top-N heapsort - -> Append (actual rows=77766 loops=1) - -> Seq Scan on _hyper_7_24_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Seq Scan on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_30_chunk (actual rows=13440 loops=1) - -> Seq Scan on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Seq Scan on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_29_chunk (actual rows=12482 loops=1) -(13 rows) - --- test hypertable with space partitioning ORDER BY non-time column --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY device_id, time LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------ - Limit (actual rows=1 loops=1) - -> Sort (actual rows=1 loops=1) - Sort Key: _hyper_7_23_chunk.device_id, _hyper_7_23_chunk."time" - Sort Method: top-N heapsort - -> Append (actual rows=77766 loops=1) - -> Seq Scan on _hyper_7_23_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_24_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_25_chunk (actual rows=12482 loops=1) - -> Seq Scan on _hyper_7_26_chunk (actual rows=13440 loops=1) - -> Seq Scan on _hyper_7_27_chunk (actual rows=6241 loops=1) - -> Seq Scan on _hyper_7_28_chunk (actual rows=6720 loops=1) - -> Seq Scan on _hyper_7_29_chunk (actual rows=12482 loops=1) - -> Seq Scan on _hyper_7_30_chunk (actual rows=13440 loops=1) -(13 rows) - -- test hypertable with 2 space dimensions :PREFIX SELECT time, device_id, value @@ -1211,27 +534,27 @@ ORDER BY time DESC; Custom Scan (ChunkAppend) on space2 (actual rows=116649 loops=1) Order: space2."time" DESC -> Merge Append (actual rows=56169 loops=1) - Sort Key: _hyper_8_47_chunk."time" DESC - -> Index Scan using _hyper_8_47_chunk_space2_time_idx on _hyper_8_47_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_45_chunk_space2_time_idx on _hyper_8_45_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_43_chunk_space2_time_idx on _hyper_8_43_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_41_chunk_space2_time_idx on _hyper_8_41_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_39_chunk_space2_time_idx on _hyper_8_39_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_37_chunk_space2_time_idx on _hyper_8_37_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_35_chunk_space2_time_idx on _hyper_8_35_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_33_chunk_space2_time_idx on _hyper_8_33_chunk (actual rows=6241 loops=1) - -> Index Scan using _hyper_8_31_chunk_space2_time_idx on _hyper_8_31_chunk (actual rows=6241 loops=1) + Sort Key: _hyper_6_36_chunk."time" DESC + -> Index Scan using _hyper_6_36_chunk_space2_time_idx on _hyper_6_36_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_34_chunk_space2_time_idx on _hyper_6_34_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_32_chunk_space2_time_idx on _hyper_6_32_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_30_chunk_space2_time_idx on _hyper_6_30_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_28_chunk_space2_time_idx on _hyper_6_28_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_26_chunk_space2_time_idx on _hyper_6_26_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_24_chunk_space2_time_idx on _hyper_6_24_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_22_chunk_space2_time_idx on _hyper_6_22_chunk (actual rows=6241 loops=1) + -> Index Scan using _hyper_6_20_chunk_space2_time_idx on _hyper_6_20_chunk (actual rows=6241 loops=1) -> Merge Append (actual rows=60480 loops=1) - Sort Key: _hyper_8_48_chunk."time" DESC - -> Index Scan using _hyper_8_48_chunk_space2_time_idx on _hyper_8_48_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_46_chunk_space2_time_idx on _hyper_8_46_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_44_chunk_space2_time_idx on _hyper_8_44_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_42_chunk_space2_time_idx on _hyper_8_42_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_40_chunk_space2_time_idx on _hyper_8_40_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_38_chunk_space2_time_idx on _hyper_8_38_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_36_chunk_space2_time_idx on _hyper_8_36_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_34_chunk_space2_time_idx on _hyper_8_34_chunk (actual rows=6720 loops=1) - -> Index Scan using _hyper_8_32_chunk_space2_time_idx on _hyper_8_32_chunk (actual rows=6720 loops=1) + Sort Key: _hyper_6_37_chunk."time" DESC + -> Index Scan using _hyper_6_37_chunk_space2_time_idx on _hyper_6_37_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_35_chunk_space2_time_idx on _hyper_6_35_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_33_chunk_space2_time_idx on _hyper_6_33_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_31_chunk_space2_time_idx on _hyper_6_31_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_29_chunk_space2_time_idx on _hyper_6_29_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_27_chunk_space2_time_idx on _hyper_6_27_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_25_chunk_space2_time_idx on _hyper_6_25_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_23_chunk_space2_time_idx on _hyper_6_23_chunk (actual rows=6720 loops=1) + -> Index Scan using _hyper_6_21_chunk_space2_time_idx on _hyper_6_21_chunk (actual rows=6720 loops=1) (24 rows) -- test hypertable with 3 space dimensions @@ -1244,829 +567,67 @@ ORDER BY time DESC; Custom Scan (ChunkAppend) on space3 (actual rows=103688 loops=1) Order: space3."time" DESC -> Merge Append (actual rows=49928 loops=1) - Sort Key: _hyper_9_63_chunk."time" DESC - -> Index Only Scan using _hyper_9_63_chunk_space3_time_idx on _hyper_9_63_chunk (actual rows=6241 loops=1) + Sort Key: _hyper_7_52_chunk."time" DESC + -> Index Only Scan using _hyper_7_52_chunk_space3_time_idx on _hyper_7_52_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_61_chunk_space3_time_idx on _hyper_9_61_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_50_chunk_space3_time_idx on _hyper_7_50_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_59_chunk_space3_time_idx on _hyper_9_59_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_48_chunk_space3_time_idx on _hyper_7_48_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_57_chunk_space3_time_idx on _hyper_9_57_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_46_chunk_space3_time_idx on _hyper_7_46_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_55_chunk_space3_time_idx on _hyper_9_55_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_44_chunk_space3_time_idx on _hyper_7_44_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_53_chunk_space3_time_idx on _hyper_9_53_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_42_chunk_space3_time_idx on _hyper_7_42_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_51_chunk_space3_time_idx on _hyper_9_51_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_40_chunk_space3_time_idx on _hyper_7_40_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 - -> Index Only Scan using _hyper_9_49_chunk_space3_time_idx on _hyper_9_49_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_7_38_chunk_space3_time_idx on _hyper_7_38_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 -> Merge Append (actual rows=53760 loops=1) - Sort Key: _hyper_9_64_chunk."time" DESC - -> Index Only Scan using _hyper_9_64_chunk_space3_time_idx on _hyper_9_64_chunk (actual rows=6720 loops=1) + Sort Key: _hyper_7_53_chunk."time" DESC + -> Index Only Scan using _hyper_7_53_chunk_space3_time_idx on _hyper_7_53_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_62_chunk_space3_time_idx on _hyper_9_62_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_51_chunk_space3_time_idx on _hyper_7_51_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_60_chunk_space3_time_idx on _hyper_9_60_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_49_chunk_space3_time_idx on _hyper_7_49_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_58_chunk_space3_time_idx on _hyper_9_58_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_47_chunk_space3_time_idx on _hyper_7_47_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_56_chunk_space3_time_idx on _hyper_9_56_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_45_chunk_space3_time_idx on _hyper_7_45_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_54_chunk_space3_time_idx on _hyper_9_54_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_43_chunk_space3_time_idx on _hyper_7_43_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_52_chunk_space3_time_idx on _hyper_9_52_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_41_chunk_space3_time_idx on _hyper_7_41_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_9_50_chunk_space3_time_idx on _hyper_9_50_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_7_39_chunk_space3_time_idx on _hyper_7_39_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 (38 rows) --- expressions in ORDER BY clause -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=10 loops=1) - -> Custom Scan (ChunkAppend) on space (actual rows=10 loops=1) - Order: time_bucket('@ 1 hour'::interval, space."time") - -> Merge Append (actual rows=10 loops=1) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_24_chunk."time")) - -> Index Only Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=10 loops=1) - Heap Fetches: 10 - -> Index Only Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Index Only Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=1 loops=1) - Heap Fetches: 1 - -> Merge Append (never executed) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_23_chunk."time")) - -> Index Only Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (never executed) - Heap Fetches: 0 -(23 rows) - -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 DESC LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=10 loops=1) - -> Custom Scan (ChunkAppend) on space (actual rows=10 loops=1) - Order: time_bucket('@ 1 hour'::interval, space."time") DESC - -> Merge Append (actual rows=10 loops=1) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_29_chunk."time")) DESC - -> Index Only Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=3 loops=1) - Heap Fetches: 3 - -> Index Only Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=2 loops=1) - Heap Fetches: 2 - -> Index Only Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=6 loops=1) - Heap Fetches: 6 - -> Index Only Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=2 loops=1) - Heap Fetches: 2 - -> Merge Append (never executed) - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_30_chunk."time")) DESC - -> Index Only Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (never executed) - Heap Fetches: 0 - -> Index Only Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (never executed) - Heap Fetches: 0 -(23 rows) - --- test LATERAL with correlated query --- only last chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=1 loops=3) - Order: o."time" DESC - Chunks excluded during startup: 0 - Chunks excluded during runtime: 2 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_1 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(13 rows) - --- test LATERAL with correlated query --- only 2nd chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 -) l ON true; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Nested Loop Left Join (actual rows=2 loops=1) - -> Function Scan on generate_series g (actual rows=2 loops=1) - -> Limit (actual rows=1 loops=2) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=1 loops=2) - Order: o."time" - Chunks excluded during startup: 0 - Chunks excluded during runtime: 2 - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_1 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 (actual rows=1 loops=2) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_3 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(13 rows) - --- test startup and runtime exclusion together -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=1 loops=3) - Order: o."time" DESC - Chunks excluded during startup: 0 - Chunks excluded during runtime: 2 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_1 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 (never executed) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) -(13 rows) - --- test startup and runtime exclusion together --- all chunks should be filtered -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=0 loops=3) - -> Custom Scan (ChunkAppend) on ordered_append o (actual rows=0 loops=3) - Order: o."time" DESC - Chunks excluded during startup: 3 -(6 rows) - --- test CTE --- no chunk exclusion for CTE because cte query is not pulled up -:PREFIX WITH cte AS (SELECT * FROM ordered_append ORDER BY time) -SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - CTE Scan on cte (actual rows=73443 loops=1) - Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - CTE cte - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=73443 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=20160 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=30240 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=23043 loops=1) -(8 rows) - --- test JOIN --- no exclusion on joined table because quals are not propagated yet -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN ordered_append o2 ON o1.time = o2.time -WHERE o1.time < '2000-02-01' -ORDER BY o1.time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- - Merge Join (actual rows=220329 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=73443 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20160 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (actual rows=30240 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (actual rows=23043 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Materialize (actual rows=220327 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=73443 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=20160 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (actual rows=30240 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (actual rows=23043 loops=1) - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) -(19 rows) - --- test JOIN --- last chunk of o2 should not be executed -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN (SELECT * FROM ordered_append o2 ORDER BY time) o2 ON o1.time = o2.time -WHERE o1.time < '2000-01-08' -ORDER BY o1.time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- - Merge Join (actual rows=90720 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=30240 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20160 loops=1) - Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (actual rows=10080 loops=1) - Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) - -> Materialize (actual rows=90721 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=30241 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=20160 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (actual rows=10081 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test subquery --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append WHERE time = (SELECT max(time) FROM ordered_append) ORDER BY time; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------ - Custom Scan (ChunkAppend) on ordered_append (actual rows=3 loops=1) - Chunks excluded during runtime: 2 - InitPlan 2 (returns $1) - -> Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append ordered_append_1 (actual rows=1 loops=1) - Order: ordered_append_1."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk _hyper_1_3_chunk_1 (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk _hyper_1_2_chunk_1 (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk _hyper_1_1_chunk_1 (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" = $1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" = $1) - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=3 loops=1) - Index Cond: ("time" = $1) -(23 rows) - --- test join against max query --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append o1 INNER JOIN (SELECT max(time) AS max_time FROM ordered_append) o2 ON o1.time = o2.max_time ORDER BY time; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Sort (actual rows=3 loops=1) - Sort Key: o1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=3 loops=1) - -> Result (actual rows=1 loops=1) - InitPlan 1 (returns $0) - -> Limit (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=1 loops=1) - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 1 - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (never executed) - Index Cond: ("time" IS NOT NULL) - Heap Fetches: 0 - -> Append (actual rows=3 loops=1) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1 (actual rows=0 loops=1) - Index Cond: ("time" = ($0)) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ("time" = ($0)) - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_2 (actual rows=3 loops=1) - Index Cond: ("time" = ($0)) -(25 rows) - --- test ordered append with limit expression -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT (SELECT length('four')); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=4 loops=1) - InitPlan 1 (returns $0) - -> Result (actual rows=1 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=4 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=4 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(8 rows) - --- test with ordered guc disabled -SET timescaledb.enable_ordered_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Merge Append (actual rows=3 loops=1) - Sort Key: _hyper_1_1_chunk."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) -(6 rows) - -RESET timescaledb.enable_ordered_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=3 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test with chunk append disabled -SET timescaledb.enable_chunk_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Merge Append (actual rows=3 loops=1) - Sort Key: _hyper_1_1_chunk."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) -(6 rows) - -RESET timescaledb.enable_chunk_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=3 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append (actual rows=3 loops=1) - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk (never executed) -(6 rows) - --- test space partitioning with startup exclusion -:PREFIX SELECT * -FROM space WHERE time < now() ORDER BY time; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space (actual rows=77766 loops=1) - Order: space."time" - -> Merge Append (actual rows=40320 loops=1) - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk (actual rows=6720 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk (actual rows=13440 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk (actual rows=6720 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk (actual rows=13440 loops=1) - Index Cond: ("time" < now()) - -> Merge Append (actual rows=37446 loops=1) - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk (actual rows=6241 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk (actual rows=12482 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk (actual rows=6241 loops=1) - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk (actual rows=12482 loops=1) - Index Cond: ("time" < now()) -(22 rows) - --- test runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on space o (actual rows=1 loops=3) - Order: o."time" DESC - -> Merge Append (actual rows=0 loops=3) - Sort Key: o_1."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk o_1 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk o_2 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk o_3 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk o_4 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Merge Append (actual rows=1 loops=3) - Sort Key: o_5."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk o_5 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk o_6 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk o_7 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk o_8 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(25 rows) - --- test startup and runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join (actual rows=3 loops=1) - -> Function Scan on generate_series g (actual rows=3 loops=1) - -> Limit (actual rows=1 loops=3) - -> Custom Scan (ChunkAppend) on space o (actual rows=1 loops=3) - Order: o."time" DESC - -> Merge Append (actual rows=0 loops=3) - Sort Key: o_1."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk o_1 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk o_2 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk o_3 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk o_4 (actual rows=0 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Merge Append (actual rows=1 loops=3) - Sort Key: o_5."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk o_5 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk o_6 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk o_7 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk o_8 (actual rows=1 loops=3) - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) -(25 rows) - --- test JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with USING --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 USING(time) ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test NATURAL JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 NATURAL INNER JOIN ordered_append o2 ORDER BY o1.time LIMIT 100; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - Join Filter: ((o1.device_id = o2.device_id) AND (o1.value = o2.value)) - Rows Removed by Join Filter: 198 - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=100 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=298 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=100 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(16 rows) - --- test LEFT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 LEFT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Left Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test RIGHT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 RIGHT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Left Join (actual rows=100 loops=1) - Merge Cond: (o2."time" = o1."time") - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) -(14 rows) - --- test JOIN on time column with ON clause expression order switched --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with equality condition in WHERE clause --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with ORDER BY 2nd hypertable --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column and device_id --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - Join Filter: (o1.device_id = o2.device_id) - Rows Removed by Join Filter: 198 - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=100 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=298 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=100 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=100 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(16 rows) - --- test JOIN on device_id --- should not use ordered append for 2nd hypertable -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Nested Loop (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=1 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=1 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Append (actual rows=100 loops=1) - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk o2 (actual rows=100 loops=1) - Index Cond: (device_id = o1.device_id) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk o2_1 (never executed) - Index Cond: (device_id = o1.device_id) - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk o2_2 (never executed) - Index Cond: (device_id = o1.device_id) -(14 rows) - --- test JOIN on time column with implicit join --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1, ordered_append o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=34 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=34 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=34 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(14 rows) - --- test JOIN on time column with 3 hypertables --- should use 3 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time INNER JOIN ordered_append o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (o3."time" = o1."time") - -> Custom Scan (ChunkAppend) on ordered_append o3 (actual rows=12 loops=1) - Order: o3."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o3_1 (actual rows=12 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o3_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o3_3 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Merge Join (actual rows=37 loops=1) - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 (actual rows=13 loops=1) - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 (actual rows=13 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 (never executed) - -> Materialize (actual rows=37 loops=1) - -> Custom Scan (ChunkAppend) on ordered_append o2 (actual rows=13 loops=1) - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 (actual rows=13 loops=1) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 (never executed) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 (never executed) -(22 rows) - --- test with space partitioning -:PREFIX SELECT * FROM space s1 INNER JOIN space s2 ON s1.time = s2.time ORDER BY s1.time LIMIT 100; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Limit (actual rows=100 loops=1) - -> Merge Join (actual rows=100 loops=1) - Merge Cond: (s1."time" = s2."time") - -> Custom Scan (ChunkAppend) on space s1 (actual rows=17 loops=1) - Order: s1."time" - -> Merge Append (actual rows=17 loops=1) - Sort Key: s1_1."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk s1_1 (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk s1_2 (actual rows=7 loops=1) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk s1_3 (actual rows=3 loops=1) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk s1_4 (actual rows=7 loops=1) - -> Merge Append (never executed) - Sort Key: s1_5."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk s1_5 (never executed) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk s1_6 (never executed) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk s1_7 (never executed) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk s1_8 (never executed) - -> Materialize (actual rows=100 loops=1) - -> Custom Scan (ChunkAppend) on space s2 (actual rows=19 loops=1) - Order: s2."time" - -> Merge Append (actual rows=19 loops=1) - Sort Key: s2_1."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk s2_1 (actual rows=4 loops=1) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk s2_2 (actual rows=7 loops=1) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk s2_3 (actual rows=4 loops=1) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk s2_4 (actual rows=7 loops=1) - -> Merge Append (never executed) - Sort Key: s2_5."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk s2_5 (never executed) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk s2_6 (never executed) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk s2_7 (never executed) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk s2_8 (never executed) -(32 rows) - -- test COLLATION -- cant be tested in our ci because alpine doesnt support locales -- :PREFIX SELECT * FROM sortopt_test ORDER BY time, device COLLATE "en_US.utf8"; -- test NULLS FIRST :PREFIX SELECT * FROM sortopt_test ORDER BY time, device NULLS FIRST; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on sortopt_test (actual rows=12961 loops=1) Order: sortopt_test."time", sortopt_test.device NULLS FIRST - -> Index Only Scan using _hyper_10_66_chunk_time_device_nullsfirst on _hyper_10_66_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_8_55_chunk_time_device_nullsfirst on _hyper_8_55_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_10_65_chunk_time_device_nullsfirst on _hyper_10_65_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_8_54_chunk_time_device_nullsfirst on _hyper_8_54_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 (6 rows) -- test NULLS LAST :PREFIX SELECT * FROM sortopt_test ORDER BY time, device DESC NULLS LAST; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on sortopt_test (actual rows=12961 loops=1) Order: sortopt_test."time", sortopt_test.device DESC NULLS LAST - -> Index Only Scan using _hyper_10_66_chunk_time_device_nullslast on _hyper_10_66_chunk (actual rows=6720 loops=1) + -> Index Only Scan using _hyper_8_55_chunk_time_device_nullslast on _hyper_8_55_chunk (actual rows=6720 loops=1) Heap Fetches: 6720 - -> Index Only Scan using _hyper_10_65_chunk_time_device_nullslast on _hyper_10_65_chunk (actual rows=6241 loops=1) + -> Index Only Scan using _hyper_8_54_chunk_time_device_nullslast on _hyper_8_54_chunk (actual rows=6241 loops=1) Heap Fetches: 6241 (6 rows) diff --git a/test/expected/plan_ordered_append-9.6.out b/test/expected/plan_ordered_append-9.6.out index 5faa90343..610b57528 100644 --- a/test/expected/plan_ordered_append-9.6.out +++ b/test/expected/plan_ordered_append-9.6.out @@ -42,25 +42,12 @@ INSERT INTO devices VALUES (1,'Device 1'), (2,'Device 2'), (3,'Device 3'); --- create a table where we create chunks in order -CREATE TABLE ordered_append(time timestamptz NOT NULL, device_id INT, value float); -SELECT create_hypertable('ordered_append','time'); - create_hypertable ------------------------------ - (1,public,ordered_append,t) -(1 row) - -CREATE index on ordered_append(time DESC,device_id); -CREATE index on ordered_append(device_id,time DESC); -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 1, 0.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 2, 1.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 3, 2.5; -- create a second table where we create chunks in reverse order CREATE TABLE ordered_append_reverse(time timestamptz NOT NULL, device_id INT, value float); SELECT create_hypertable('ordered_append_reverse','time'); create_hypertable ------------------------------------- - (2,public,ordered_append_reverse,t) + (1,public,ordered_append_reverse,t) (1 row) INSERT INTO ordered_append_reverse SELECT generate_series('2000-01-18'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 0.5; @@ -74,7 +61,7 @@ CREATE TABLE IF NOT EXISTS dimension_last( SELECT create_hypertable('dimension_last', 'time', chunk_time_interval => interval '1day', if_not_exists => True); create_hypertable ----------------------------- - (3,public,dimension_last,t) + (2,public,dimension_last,t) (1 row) -- table with only dimension column @@ -84,7 +71,7 @@ CREATE TABLE IF NOT EXISTS dimension_only( SELECT create_hypertable('dimension_only', 'time', chunk_time_interval => interval '1day', if_not_exists => True); create_hypertable ----------------------------- - (4,public,dimension_only,t) + (3,public,dimension_only,t) (1 row) INSERT INTO dimension_last SELECT 1,1,'Device 1',generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-04 23:59:00+0'::timestamptz,'1m'::interval); @@ -94,7 +81,6 @@ INSERT INTO dimension_only VALUES ('2000-01-05'), ('2000-01-07'); ANALYZE devices; -ANALYZE ordered_append; ANALYZE ordered_append_reverse; ANALYZE dimension_last; ANALYZE dimension_only; @@ -103,7 +89,7 @@ CREATE TABLE ht_missing_indexes(time timestamptz NOT NULL, device_id int, value SELECT create_hypertable('ht_missing_indexes','time'); create_hypertable --------------------------------- - (5,public,ht_missing_indexes,t) + (4,public,ht_missing_indexes,t) (1 row) INSERT INTO ht_missing_indexes SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 1, 0.5; @@ -123,7 +109,7 @@ CREATE TABLE ht_dropped_columns(c1 int, c2 int, c3 int, c4 int, c5 int, time tim SELECT create_hypertable('ht_dropped_columns','time'); create_hypertable --------------------------------- - (6,public,ht_dropped_columns,t) + (5,public,ht_dropped_columns,t) (1 row) ALTER TABLE ht_dropped_columns DROP COLUMN c1; @@ -137,31 +123,17 @@ INSERT INTO ht_dropped_columns(time,device_id,value) SELECT generate_series('200 ALTER TABLE ht_dropped_columns DROP COLUMN c5; INSERT INTO ht_dropped_columns(time,device_id,value) SELECT generate_series('2000-01-29'::timestamptz,'2000-01-30'::timestamptz,'1m'::interval), 1, 0.5; ANALYZE ht_dropped_columns; -CREATE TABLE space(time timestamptz NOT NULL, device_id int NOT NULL, value float); -SELECT create_hypertable('space','time','device_id',number_partitions:=4); - create_hypertable --------------------- - (7,public,space,t) -(1 row) - -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 2, 2.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 3, 3.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 4, 4.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 5, 5.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 6, 6.5; -ANALYZE space; CREATE TABLE space2(time timestamptz NOT NULL, device_id int NOT NULL, tag_id int NOT NULL, value float); SELECT create_hypertable('space2','time','device_id',number_partitions:=3); create_hypertable --------------------- - (8,public,space2,t) + (6,public,space2,t) (1 row) SELECT add_dimension('space2','tag_id',number_partitions:=3); - add_dimension ------------------------------ - (11,public,space2,tag_id,t) + add_dimension +---------------------------- + (8,public,space2,tag_id,t) (1 row) INSERT INTO space2 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1, 1.5; @@ -178,19 +150,19 @@ CREATE TABLE space3(time timestamptz NOT NULL, x int NOT NULL, y int NOT NULL, z SELECT create_hypertable('space3','time','x',number_partitions:=2); create_hypertable --------------------- - (9,public,space3,t) + (7,public,space3,t) (1 row) SELECT add_dimension('space3','y',number_partitions:=2); add_dimension ------------------------ - (14,public,space3,y,t) + (11,public,space3,y,t) (1 row) SELECT add_dimension('space3','z',number_partitions:=2); add_dimension ------------------------ - (15,public,space3,z,t) + (12,public,space3,z,t) (1 row) INSERT INTO space3 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1, 1, 1.5; @@ -204,9 +176,9 @@ INSERT INTO space3 SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01' ANALYZE space3; CREATE TABLE sortopt_test(time timestamptz NOT NULL, device TEXT); SELECT create_hypertable('sortopt_test','time',create_default_indexes:=false); - create_hypertable ----------------------------- - (10,public,sortopt_test,t) + create_hypertable +--------------------------- + (8,public,sortopt_test,t) (1 row) -- since alpine does not support locales we cant test collations in our ci @@ -232,105 +204,64 @@ FROM INNER JOIN _timescaledb_catalog.dimension d ON ds.dimension_id = d.id INNER JOIN _timescaledb_catalog.hypertable ht ON d.hypertable_id = ht.id ORDER BY ht.table_name, range_start, chunk; - hypertable | chunk | range_start -------------------------+--------------------+---------------------- - dimension_last | _hyper_3_7_chunk | 946684800000000 - dimension_last | _hyper_3_8_chunk | 946771200000000 - dimension_last | _hyper_3_9_chunk | 946857600000000 - dimension_last | _hyper_3_10_chunk | 946944000000000 - dimension_only | _hyper_4_11_chunk | 946684800000000 - dimension_only | _hyper_4_12_chunk | 946857600000000 - dimension_only | _hyper_4_13_chunk | 947030400000000 - dimension_only | _hyper_4_14_chunk | 947203200000000 - ht_dropped_columns | _hyper_6_18_chunk | 946512000000000 - ht_dropped_columns | _hyper_6_19_chunk | 947116800000000 - ht_dropped_columns | _hyper_6_20_chunk | 947721600000000 - ht_dropped_columns | _hyper_6_21_chunk | 948326400000000 - ht_dropped_columns | _hyper_6_22_chunk | 948931200000000 - ht_missing_indexes | _hyper_5_15_chunk | 946512000000000 - ht_missing_indexes | _hyper_5_16_chunk | 947116800000000 - ht_missing_indexes | _hyper_5_17_chunk | 947721600000000 - ordered_append | _hyper_1_1_chunk | 946512000000000 - ordered_append | _hyper_1_2_chunk | 947116800000000 - ordered_append | _hyper_1_3_chunk | 947721600000000 - ordered_append_reverse | _hyper_2_6_chunk | 946512000000000 - ordered_append_reverse | _hyper_2_5_chunk | 947116800000000 - ordered_append_reverse | _hyper_2_4_chunk | 947721600000000 - sortopt_test | _hyper_10_66_chunk | 946512000000000 - sortopt_test | _hyper_10_65_chunk | 947116800000000 - space | _hyper_7_24_chunk | -9223372036854775808 - space | _hyper_7_26_chunk | 946512000000000 - space | _hyper_7_28_chunk | 946512000000000 - space | _hyper_7_30_chunk | 946512000000000 - space | _hyper_7_23_chunk | 947116800000000 - space | _hyper_7_25_chunk | 947116800000000 - space | _hyper_7_27_chunk | 947116800000000 - space | _hyper_7_29_chunk | 947116800000000 - space2 | _hyper_8_32_chunk | -9223372036854775808 - space2 | _hyper_8_34_chunk | -9223372036854775808 - space2 | _hyper_8_36_chunk | -9223372036854775808 - space2 | _hyper_8_38_chunk | -9223372036854775808 - space2 | _hyper_8_44_chunk | -9223372036854775808 - space2 | _hyper_8_40_chunk | 946512000000000 - space2 | _hyper_8_42_chunk | 946512000000000 - space2 | _hyper_8_46_chunk | 946512000000000 - space2 | _hyper_8_48_chunk | 946512000000000 - space2 | _hyper_8_31_chunk | 947116800000000 - space2 | _hyper_8_33_chunk | 947116800000000 - space2 | _hyper_8_35_chunk | 947116800000000 - space2 | _hyper_8_37_chunk | 947116800000000 - space2 | _hyper_8_39_chunk | 947116800000000 - space2 | _hyper_8_41_chunk | 947116800000000 - space2 | _hyper_8_43_chunk | 947116800000000 - space2 | _hyper_8_45_chunk | 947116800000000 - space2 | _hyper_8_47_chunk | 947116800000000 - space3 | _hyper_9_50_chunk | -9223372036854775808 - space3 | _hyper_9_52_chunk | -9223372036854775808 - space3 | _hyper_9_54_chunk | -9223372036854775808 - space3 | _hyper_9_56_chunk | -9223372036854775808 - space3 | _hyper_9_58_chunk | -9223372036854775808 - space3 | _hyper_9_60_chunk | -9223372036854775808 - space3 | _hyper_9_62_chunk | -9223372036854775808 - space3 | _hyper_9_64_chunk | 946512000000000 - space3 | _hyper_9_49_chunk | 947116800000000 - space3 | _hyper_9_51_chunk | 947116800000000 - space3 | _hyper_9_53_chunk | 947116800000000 - space3 | _hyper_9_55_chunk | 947116800000000 - space3 | _hyper_9_57_chunk | 947116800000000 - space3 | _hyper_9_59_chunk | 947116800000000 - space3 | _hyper_9_61_chunk | 947116800000000 - space3 | _hyper_9_63_chunk | 947116800000000 -(66 rows) - --- test ASC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - --- test DESC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk -(6 rows) + hypertable | chunk | range_start +------------------------+-------------------+---------------------- + dimension_last | _hyper_2_4_chunk | 946684800000000 + dimension_last | _hyper_2_5_chunk | 946771200000000 + dimension_last | _hyper_2_6_chunk | 946857600000000 + dimension_last | _hyper_2_7_chunk | 946944000000000 + dimension_only | _hyper_3_8_chunk | 946684800000000 + dimension_only | _hyper_3_9_chunk | 946857600000000 + dimension_only | _hyper_3_10_chunk | 947030400000000 + dimension_only | _hyper_3_11_chunk | 947203200000000 + ht_dropped_columns | _hyper_5_15_chunk | 946512000000000 + ht_dropped_columns | _hyper_5_16_chunk | 947116800000000 + ht_dropped_columns | _hyper_5_17_chunk | 947721600000000 + ht_dropped_columns | _hyper_5_18_chunk | 948326400000000 + ht_dropped_columns | _hyper_5_19_chunk | 948931200000000 + ht_missing_indexes | _hyper_4_12_chunk | 946512000000000 + ht_missing_indexes | _hyper_4_13_chunk | 947116800000000 + ht_missing_indexes | _hyper_4_14_chunk | 947721600000000 + ordered_append_reverse | _hyper_1_3_chunk | 946512000000000 + ordered_append_reverse | _hyper_1_2_chunk | 947116800000000 + ordered_append_reverse | _hyper_1_1_chunk | 947721600000000 + sortopt_test | _hyper_8_55_chunk | 946512000000000 + sortopt_test | _hyper_8_54_chunk | 947116800000000 + space2 | _hyper_6_21_chunk | -9223372036854775808 + space2 | _hyper_6_23_chunk | -9223372036854775808 + space2 | _hyper_6_25_chunk | -9223372036854775808 + space2 | _hyper_6_27_chunk | -9223372036854775808 + space2 | _hyper_6_33_chunk | -9223372036854775808 + space2 | _hyper_6_29_chunk | 946512000000000 + space2 | _hyper_6_31_chunk | 946512000000000 + space2 | _hyper_6_35_chunk | 946512000000000 + space2 | _hyper_6_37_chunk | 946512000000000 + space2 | _hyper_6_20_chunk | 947116800000000 + space2 | _hyper_6_22_chunk | 947116800000000 + space2 | _hyper_6_24_chunk | 947116800000000 + space2 | _hyper_6_26_chunk | 947116800000000 + space2 | _hyper_6_28_chunk | 947116800000000 + space2 | _hyper_6_30_chunk | 947116800000000 + space2 | _hyper_6_32_chunk | 947116800000000 + space2 | _hyper_6_34_chunk | 947116800000000 + space2 | _hyper_6_36_chunk | 947116800000000 + space3 | _hyper_7_39_chunk | -9223372036854775808 + space3 | _hyper_7_41_chunk | -9223372036854775808 + space3 | _hyper_7_43_chunk | -9223372036854775808 + space3 | _hyper_7_45_chunk | -9223372036854775808 + space3 | _hyper_7_47_chunk | -9223372036854775808 + space3 | _hyper_7_49_chunk | -9223372036854775808 + space3 | _hyper_7_51_chunk | -9223372036854775808 + space3 | _hyper_7_53_chunk | 946512000000000 + space3 | _hyper_7_38_chunk | 947116800000000 + space3 | _hyper_7_40_chunk | 947116800000000 + space3 | _hyper_7_42_chunk | 947116800000000 + space3 | _hyper_7_44_chunk | 947116800000000 + space3 | _hyper_7_46_chunk | 947116800000000 + space3 | _hyper_7_48_chunk | 947116800000000 + space3 | _hyper_7_50_chunk | 947116800000000 + space3 | _hyper_7_52_chunk | 947116800000000 +(55 rows) -- test ASC for reverse ordered chunks :PREFIX SELECT @@ -342,9 +273,9 @@ ORDER BY time ASC LIMIT 1; Limit -> Custom Scan (ChunkAppend) on ordered_append_reverse Order: ordered_append_reverse."time" - -> Index Scan Backward using _hyper_2_6_chunk_ordered_append_reverse_time_idx on _hyper_2_6_chunk - -> Index Scan Backward using _hyper_2_5_chunk_ordered_append_reverse_time_idx on _hyper_2_5_chunk - -> Index Scan Backward using _hyper_2_4_chunk_ordered_append_reverse_time_idx on _hyper_2_4_chunk + -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_reverse_time_idx on _hyper_1_3_chunk + -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_reverse_time_idx on _hyper_1_2_chunk + -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_reverse_time_idx on _hyper_1_1_chunk (6 rows) -- test DESC for reverse ordered chunks @@ -357,340 +288,9 @@ ORDER BY time DESC LIMIT 1; Limit -> Custom Scan (ChunkAppend) on ordered_append_reverse Order: ordered_append_reverse."time" DESC - -> Index Scan using _hyper_2_4_chunk_ordered_append_reverse_time_idx on _hyper_2_4_chunk - -> Index Scan using _hyper_2_5_chunk_ordered_append_reverse_time_idx on _hyper_2_5_chunk - -> Index Scan using _hyper_2_6_chunk_ordered_append_reverse_time_idx on _hyper_2_6_chunk -(6 rows) - --- test query with ORDER BY column not in targetlist -:PREFIX SELECT - device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - --- ORDER BY may include other columns after time column -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC, ordered_append.device_id - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_device_id_idx on _hyper_1_3_chunk - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_device_id_idx on _hyper_1_2_chunk - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_device_id_idx on _hyper_1_1_chunk -(6 rows) - --- test RECORD in targetlist -:PREFIX SELECT - (time, device_id, value) -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC, ordered_append.device_id - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_device_id_idx on _hyper_1_3_chunk - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_device_id_idx on _hyper_1_2_chunk - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_device_id_idx on _hyper_1_1_chunk -(6 rows) - --- test sort column not in targetlist -:PREFIX SELECT - time_bucket('1h',time) -FROM ordered_append -ORDER BY time DESC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk -(6 rows) - --- queries with ORDER BY non-time column shouldn't use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Limit - -> Merge Append - Sort Key: _hyper_1_1_chunk.device_id - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk -(6 rows) - --- time column must be primary sort order -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id, time LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------ - Limit - -> Sort - Sort Key: _hyper_1_1_chunk.device_id, _hyper_1_1_chunk."time" - -> Append - -> Seq Scan on _hyper_1_1_chunk - -> Seq Scan on _hyper_1_2_chunk - -> Seq Scan on _hyper_1_3_chunk -(7 rows) - --- queries without LIMIT should use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC; - QUERY PLAN ----------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(5 rows) - --- queries without ORDER BY shouldnt use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -LIMIT 1; - QUERY PLAN ------------------------------------------- - Limit - -> Append - -> Seq Scan on _hyper_1_1_chunk - -> Seq Scan on _hyper_1_2_chunk - -> Seq Scan on _hyper_1_3_chunk -(5 rows) - --- test interaction with constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) -(7 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time DESC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------ - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) -(7 rows) - --- test interaction with constraint aware append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" > now_s()) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" > now_s()) -(8 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" < now_s()) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" < now_s()) -(8 rows) - --- test constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() AND time < '2000-01-10' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: (("time" > now_s()) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) -(6 rows) - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() AND time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - Chunks excluded during startup: 1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: (("time" < now_s()) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) -(6 rows) - --- min/max queries -:PREFIX SELECT max(time) FROM ordered_append; - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Result - InitPlan 1 (returns $0) - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" IS NOT NULL) -(11 rows) - -:PREFIX SELECT min(time) FROM ordered_append; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Result - InitPlan 1 (returns $0) - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Only Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" IS NOT NULL) -(11 rows) - --- test first/last (doesn't use ordered append yet) -:PREFIX SELECT first(time, time) FROM ordered_append; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Result - InitPlan 1 (returns $0) - -> Limit - -> Result - -> Merge Append - Sort Key: _hyper_1_1_chunk."time" - -> Index Only Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" IS NOT NULL) -(12 rows) - -:PREFIX SELECT last(time, time) FROM ordered_append; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Result - InitPlan 1 (returns $0) - -> Limit - -> Result - -> Merge Append - Sort Key: _hyper_1_1_chunk."time" DESC - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" IS NOT NULL) -(12 rows) - --- test query with time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: time_bucket('@ 1 day'::interval, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time_bucket('1d',time) LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: time_bucket('@ 1 day'::interval, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk + -> Index Scan using _hyper_1_1_chunk_ordered_append_reverse_time_idx on _hyper_1_1_chunk + -> Index Scan using _hyper_1_2_chunk_ordered_append_reverse_time_idx on _hyper_1_2_chunk + -> Index Scan using _hyper_1_3_chunk_ordered_append_reverse_time_idx on _hyper_1_3_chunk (6 rows) -- test query with ORDER BY time_bucket, device_id @@ -703,45 +303,15 @@ ORDER BY time_bucket('1d',time), device_id LIMIT 1; ----------------------------------------------------------------------------------------------------------- Limit -> Sort - Sort Key: (time_bucket('@ 1 day'::interval, _hyper_3_7_chunk."time")), _hyper_3_7_chunk.device_id + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id -> Result -> Append - -> Seq Scan on _hyper_3_7_chunk - -> Seq Scan on _hyper_3_8_chunk - -> Seq Scan on _hyper_3_9_chunk - -> Seq Scan on _hyper_3_10_chunk + -> Seq Scan on _hyper_2_4_chunk + -> Seq Scan on _hyper_2_5_chunk + -> Seq Scan on _hyper_2_6_chunk + -> Seq Scan on _hyper_2_7_chunk (9 rows) --- test query with ORDER BY date_trunc -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY date_trunc('day', time) LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: date_trunc('day'::text, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - --- test query with ORDER BY date_trunc -:PREFIX SELECT - date_trunc('day',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: date_trunc('day'::text, ordered_append."time") - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - -- test query with ORDER BY date_trunc, device_id -- must not use ordered append :PREFIX SELECT @@ -752,110 +322,15 @@ ORDER BY 1,2 LIMIT 1; -------------------------------------------------------------------------------------------------- Limit -> Sort - Sort Key: (date_trunc('day'::text, _hyper_3_7_chunk."time")), _hyper_3_7_chunk.device_id + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id -> Result -> Append - -> Seq Scan on _hyper_3_7_chunk - -> Seq Scan on _hyper_3_8_chunk - -> Seq Scan on _hyper_3_9_chunk - -> Seq Scan on _hyper_3_10_chunk + -> Seq Scan on _hyper_2_4_chunk + -> Seq Scan on _hyper_2_5_chunk + -> Seq Scan on _hyper_2_6_chunk + -> Seq Scan on _hyper_2_7_chunk (9 rows) --- test query with now() should result in ordered ChunkAppend -:PREFIX SELECT * FROM ordered_append WHERE time < now() + '1 month' -ORDER BY time DESC limit 1; - QUERY PLAN -------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" < (now() + '@ 1 mon'::interval)) -(10 rows) - --- test CTE -:PREFIX WITH i AS (SELECT * FROM ordered_append WHERE time < now() ORDER BY time DESC limit 100) -SELECT * FROM i; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - CTE Scan on i - CTE i - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" < now()) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" < now()) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" < now()) -(12 rows) - --- test LATERAL with ordered append in the outer query -:PREFIX SELECT * FROM ordered_append, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; - QUERY PLAN -------------------------------------------------------------------------------------------------- - Limit - -> Nested Loop - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Materialize - -> Values Scan on "*VALUES*" -(9 rows) - --- test LATERAL with ordered append in the lateral query -:PREFIX SELECT * FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM ordered_append ORDER BY time DESC limit 2) l; - QUERY PLAN -------------------------------------------------------------------------------------------------------- - Nested Loop - -> Values Scan on "*VALUES*" - -> Materialize - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk -(9 rows) - --- test plan with best index is chosen --- this should use device_id, time index -:PREFIX SELECT * FROM ordered_append WHERE device_id = 1 ORDER BY time DESC LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk - Index Cond: (device_id = 1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk - Index Cond: (device_id = 1) - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk - Index Cond: (device_id = 1) -(9 rows) - --- test plan with best index is chosen --- this should use time index -:PREFIX SELECT * FROM ordered_append ORDER BY time DESC LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk -(6 rows) - -- test with table with only dimension column :PREFIX SELECT * FROM dimension_only ORDER BY time DESC LIMIT 1; QUERY PLAN @@ -863,10 +338,10 @@ SELECT * FROM i; Limit -> Custom Scan (ChunkAppend) on dimension_only Order: dimension_only."time" DESC - -> Index Only Scan using _hyper_4_14_chunk_dimension_only_time_idx on _hyper_4_14_chunk - -> Index Only Scan using _hyper_4_13_chunk_dimension_only_time_idx on _hyper_4_13_chunk - -> Index Only Scan using _hyper_4_12_chunk_dimension_only_time_idx on _hyper_4_12_chunk - -> Index Only Scan using _hyper_4_11_chunk_dimension_only_time_idx on _hyper_4_11_chunk + -> Index Only Scan using _hyper_3_11_chunk_dimension_only_time_idx on _hyper_3_11_chunk + -> Index Only Scan using _hyper_3_10_chunk_dimension_only_time_idx on _hyper_3_10_chunk + -> Index Only Scan using _hyper_3_9_chunk_dimension_only_time_idx on _hyper_3_9_chunk + -> Index Only Scan using _hyper_3_8_chunk_dimension_only_time_idx on _hyper_3_8_chunk (7 rows) -- test LEFT JOIN against hypertable @@ -875,23 +350,23 @@ FROM dimension_last LEFT JOIN dimension_only USING (time) ORDER BY dimension_last.time DESC LIMIT 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Limit -> Nested Loop Left Join - Join Filter: (dimension_last."time" = _hyper_4_14_chunk."time") + Join Filter: (dimension_last."time" = _hyper_3_11_chunk."time") -> Custom Scan (ChunkAppend) on dimension_last Order: dimension_last."time" DESC - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk -> Materialize -> Append - -> Seq Scan on _hyper_4_14_chunk - -> Seq Scan on _hyper_4_13_chunk - -> Seq Scan on _hyper_4_12_chunk - -> Seq Scan on _hyper_4_11_chunk + -> Seq Scan on _hyper_3_11_chunk + -> Seq Scan on _hyper_3_10_chunk + -> Seq Scan on _hyper_3_9_chunk + -> Seq Scan on _hyper_3_8_chunk (15 rows) -- test INNER JOIN against non-hypertable @@ -906,18 +381,18 @@ LIMIT 2; -> Nested Loop -> Custom Scan (ChunkAppend) on dimension_only Order: dimension_only."time" DESC - -> Index Only Scan using _hyper_4_14_chunk_dimension_only_time_idx on _hyper_4_14_chunk - -> Index Only Scan using _hyper_4_13_chunk_dimension_only_time_idx on _hyper_4_13_chunk - -> Index Only Scan using _hyper_4_12_chunk_dimension_only_time_idx on _hyper_4_12_chunk - -> Index Only Scan using _hyper_4_11_chunk_dimension_only_time_idx on _hyper_4_11_chunk + -> Index Only Scan using _hyper_3_11_chunk_dimension_only_time_idx on _hyper_3_11_chunk + -> Index Only Scan using _hyper_3_10_chunk_dimension_only_time_idx on _hyper_3_10_chunk + -> Index Only Scan using _hyper_3_9_chunk_dimension_only_time_idx on _hyper_3_9_chunk + -> Index Only Scan using _hyper_3_8_chunk_dimension_only_time_idx on _hyper_3_8_chunk -> Append - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk Index Cond: ("time" = dimension_only."time") - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk Index Cond: ("time" = dimension_only."time") (17 rows) @@ -927,17 +402,17 @@ FROM dimension_last INNER JOIN devices USING(device_id) ORDER BY dimension_last.time DESC LIMIT 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Limit -> Nested Loop Join Filter: (dimension_last.device_id = devices.device_id) -> Custom Scan (ChunkAppend) on dimension_last Order: dimension_last."time" DESC - -> Index Scan using _hyper_3_10_chunk_dimension_last_time_idx on _hyper_3_10_chunk - -> Index Scan using _hyper_3_9_chunk_dimension_last_time_idx on _hyper_3_9_chunk - -> Index Scan using _hyper_3_8_chunk_dimension_last_time_idx on _hyper_3_8_chunk - -> Index Scan using _hyper_3_7_chunk_dimension_last_time_idx on _hyper_3_7_chunk + -> Index Scan using _hyper_2_7_chunk_dimension_last_time_idx on _hyper_2_7_chunk + -> Index Scan using _hyper_2_6_chunk_dimension_last_time_idx on _hyper_2_6_chunk + -> Index Scan using _hyper_2_5_chunk_dimension_last_time_idx on _hyper_2_5_chunk + -> Index Scan using _hyper_2_4_chunk_dimension_last_time_idx on _hyper_2_4_chunk -> Materialize -> Seq Scan on devices (11 rows) @@ -952,11 +427,11 @@ ORDER BY time ASC LIMIT 1; Limit -> Custom Scan (ChunkAppend) on ht_missing_indexes Order: ht_missing_indexes."time" - -> Index Scan Backward using _hyper_5_15_chunk_ht_missing_indexes_time_idx on _hyper_5_15_chunk + -> Index Scan Backward using _hyper_4_12_chunk_ht_missing_indexes_time_idx on _hyper_4_12_chunk -> Sort - Sort Key: _hyper_5_16_chunk."time" - -> Seq Scan on _hyper_5_16_chunk - -> Index Scan Backward using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk + Sort Key: _hyper_4_13_chunk."time" + -> Seq Scan on _hyper_4_13_chunk + -> Index Scan Backward using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk (8 rows) -- test hypertable with index missing on one chunk @@ -971,13 +446,13 @@ ORDER BY time DESC LIMIT 1; Limit -> Custom Scan (ChunkAppend) on ht_missing_indexes Order: ht_missing_indexes."time" DESC - -> Index Scan using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk + -> Index Scan using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk Filter: (device_id = 2) -> Sort - Sort Key: _hyper_5_16_chunk."time" DESC - -> Seq Scan on _hyper_5_16_chunk + Sort Key: _hyper_4_13_chunk."time" DESC + -> Seq Scan on _hyper_4_13_chunk Filter: (device_id = 2) - -> Index Scan using _hyper_5_15_chunk_ht_missing_indexes_time_idx on _hyper_5_15_chunk + -> Index Scan using _hyper_4_12_chunk_ht_missing_indexes_time_idx on _hyper_4_12_chunk Filter: (device_id = 2) (11 rows) @@ -994,10 +469,10 @@ ORDER BY time LIMIT 10; -> Custom Scan (ChunkAppend) on ht_missing_indexes Order: ht_missing_indexes."time" -> Sort - Sort Key: _hyper_5_16_chunk."time" - -> Seq Scan on _hyper_5_16_chunk + Sort Key: _hyper_4_13_chunk."time" + -> Seq Scan on _hyper_4_13_chunk Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_5_17_chunk_ht_missing_indexes_time_idx on _hyper_5_17_chunk + -> Index Scan Backward using _hyper_4_14_chunk_ht_missing_indexes_time_idx on _hyper_4_14_chunk Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) (9 rows) @@ -1011,11 +486,11 @@ ORDER BY time ASC LIMIT 1; Limit -> Custom Scan (ChunkAppend) on ht_dropped_columns Order: ht_dropped_columns."time" - -> Index Scan Backward using _hyper_6_18_chunk_ht_dropped_columns_time_idx on _hyper_6_18_chunk - -> Index Scan Backward using _hyper_6_19_chunk_ht_dropped_columns_time_idx on _hyper_6_19_chunk - -> Index Scan Backward using _hyper_6_20_chunk_ht_dropped_columns_time_idx on _hyper_6_20_chunk - -> Index Scan Backward using _hyper_6_21_chunk_ht_dropped_columns_time_idx on _hyper_6_21_chunk - -> Index Scan Backward using _hyper_6_22_chunk_ht_dropped_columns_time_idx on _hyper_6_22_chunk + -> Index Scan Backward using _hyper_5_15_chunk_ht_dropped_columns_time_idx on _hyper_5_15_chunk + -> Index Scan Backward using _hyper_5_16_chunk_ht_dropped_columns_time_idx on _hyper_5_16_chunk + -> Index Scan Backward using _hyper_5_17_chunk_ht_dropped_columns_time_idx on _hyper_5_17_chunk + -> Index Scan Backward using _hyper_5_18_chunk_ht_dropped_columns_time_idx on _hyper_5_18_chunk + -> Index Scan Backward using _hyper_5_19_chunk_ht_dropped_columns_time_idx on _hyper_5_19_chunk (8 rows) -- test hypertable with dropped columns @@ -1028,150 +503,18 @@ ORDER BY time DESC; ------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on ht_dropped_columns Order: ht_dropped_columns."time" DESC - -> Index Scan using _hyper_6_22_chunk_ht_dropped_columns_time_idx on _hyper_6_22_chunk + -> Index Scan using _hyper_5_19_chunk_ht_dropped_columns_time_idx on _hyper_5_19_chunk Filter: (device_id = 1) - -> Index Scan using _hyper_6_21_chunk_ht_dropped_columns_time_idx on _hyper_6_21_chunk + -> Index Scan using _hyper_5_18_chunk_ht_dropped_columns_time_idx on _hyper_5_18_chunk Filter: (device_id = 1) - -> Index Scan using _hyper_6_20_chunk_ht_dropped_columns_time_idx on _hyper_6_20_chunk + -> Index Scan using _hyper_5_17_chunk_ht_dropped_columns_time_idx on _hyper_5_17_chunk Filter: (device_id = 1) - -> Index Scan using _hyper_6_19_chunk_ht_dropped_columns_time_idx on _hyper_6_19_chunk + -> Index Scan using _hyper_5_16_chunk_ht_dropped_columns_time_idx on _hyper_5_16_chunk Filter: (device_id = 1) - -> Index Scan using _hyper_6_18_chunk_ht_dropped_columns_time_idx on _hyper_6_18_chunk + -> Index Scan using _hyper_5_15_chunk_ht_dropped_columns_time_idx on _hyper_5_15_chunk Filter: (device_id = 1) (12 rows) --- test hypertable with space partitioning -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space - Order: space."time" - -> Merge Append - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk - -> Merge Append - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk -(14 rows) - --- test hypertable with space partitioning and exclusion in space --- should remove 3 of 4 space partitions (2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id = 1 -ORDER BY time; - QUERY PLAN ---------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space - Order: space."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk - Filter: (device_id = 1) - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk - Filter: (device_id = 1) -(6 rows) - --- test hypertable with space partitioning and exclusion in space --- should remove 2 of 4 space partitions (2 + 2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id IN (1, 4) -ORDER BY time; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space - Order: space."time" - -> Merge Append - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk - Filter: (device_id = ANY ('{1,4}'::integer[])) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk - Filter: (device_id = ANY ('{1,4}'::integer[])) - -> Merge Append - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk - Filter: (device_id = ANY ('{1,4}'::integer[])) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk - Filter: (device_id = ANY ('{1,4}'::integer[])) -(14 rows) - --- test hypertable with space partitioning and reverse order -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time DESC; - QUERY PLAN ------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space - Order: space."time" DESC - -> Merge Append - Sort Key: _hyper_7_29_chunk."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk - -> Merge Append - Sort Key: _hyper_7_30_chunk."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk -(14 rows) - --- test hypertable with space partitioning ORDER BY multiple columns --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time, device_id LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------- - Limit - -> Sort - Sort Key: _hyper_7_24_chunk."time", _hyper_7_24_chunk.device_id - -> Append - -> Seq Scan on _hyper_7_24_chunk - -> Seq Scan on _hyper_7_26_chunk - -> Seq Scan on _hyper_7_28_chunk - -> Seq Scan on _hyper_7_30_chunk - -> Seq Scan on _hyper_7_23_chunk - -> Seq Scan on _hyper_7_25_chunk - -> Seq Scan on _hyper_7_27_chunk - -> Seq Scan on _hyper_7_29_chunk -(12 rows) - --- test hypertable with space partitioning ORDER BY non-time column --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY device_id, time LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------- - Limit - -> Sort - Sort Key: _hyper_7_23_chunk.device_id, _hyper_7_23_chunk."time" - -> Append - -> Seq Scan on _hyper_7_23_chunk - -> Seq Scan on _hyper_7_24_chunk - -> Seq Scan on _hyper_7_25_chunk - -> Seq Scan on _hyper_7_26_chunk - -> Seq Scan on _hyper_7_27_chunk - -> Seq Scan on _hyper_7_28_chunk - -> Seq Scan on _hyper_7_29_chunk - -> Seq Scan on _hyper_7_30_chunk -(12 rows) - -- test hypertable with 2 space dimensions :PREFIX SELECT time, device_id, value @@ -1182,27 +525,27 @@ ORDER BY time DESC; Custom Scan (ChunkAppend) on space2 Order: space2."time" DESC -> Merge Append - Sort Key: _hyper_8_47_chunk."time" DESC - -> Index Scan using _hyper_8_47_chunk_space2_time_idx on _hyper_8_47_chunk - -> Index Scan using _hyper_8_45_chunk_space2_time_idx on _hyper_8_45_chunk - -> Index Scan using _hyper_8_43_chunk_space2_time_idx on _hyper_8_43_chunk - -> Index Scan using _hyper_8_41_chunk_space2_time_idx on _hyper_8_41_chunk - -> Index Scan using _hyper_8_39_chunk_space2_time_idx on _hyper_8_39_chunk - -> Index Scan using _hyper_8_37_chunk_space2_time_idx on _hyper_8_37_chunk - -> Index Scan using _hyper_8_35_chunk_space2_time_idx on _hyper_8_35_chunk - -> Index Scan using _hyper_8_33_chunk_space2_time_idx on _hyper_8_33_chunk - -> Index Scan using _hyper_8_31_chunk_space2_time_idx on _hyper_8_31_chunk + Sort Key: _hyper_6_36_chunk."time" DESC + -> Index Scan using _hyper_6_36_chunk_space2_time_idx on _hyper_6_36_chunk + -> Index Scan using _hyper_6_34_chunk_space2_time_idx on _hyper_6_34_chunk + -> Index Scan using _hyper_6_32_chunk_space2_time_idx on _hyper_6_32_chunk + -> Index Scan using _hyper_6_30_chunk_space2_time_idx on _hyper_6_30_chunk + -> Index Scan using _hyper_6_28_chunk_space2_time_idx on _hyper_6_28_chunk + -> Index Scan using _hyper_6_26_chunk_space2_time_idx on _hyper_6_26_chunk + -> Index Scan using _hyper_6_24_chunk_space2_time_idx on _hyper_6_24_chunk + -> Index Scan using _hyper_6_22_chunk_space2_time_idx on _hyper_6_22_chunk + -> Index Scan using _hyper_6_20_chunk_space2_time_idx on _hyper_6_20_chunk -> Merge Append - Sort Key: _hyper_8_48_chunk."time" DESC - -> Index Scan using _hyper_8_48_chunk_space2_time_idx on _hyper_8_48_chunk - -> Index Scan using _hyper_8_46_chunk_space2_time_idx on _hyper_8_46_chunk - -> Index Scan using _hyper_8_44_chunk_space2_time_idx on _hyper_8_44_chunk - -> Index Scan using _hyper_8_42_chunk_space2_time_idx on _hyper_8_42_chunk - -> Index Scan using _hyper_8_40_chunk_space2_time_idx on _hyper_8_40_chunk - -> Index Scan using _hyper_8_38_chunk_space2_time_idx on _hyper_8_38_chunk - -> Index Scan using _hyper_8_36_chunk_space2_time_idx on _hyper_8_36_chunk - -> Index Scan using _hyper_8_34_chunk_space2_time_idx on _hyper_8_34_chunk - -> Index Scan using _hyper_8_32_chunk_space2_time_idx on _hyper_8_32_chunk + Sort Key: _hyper_6_37_chunk."time" DESC + -> Index Scan using _hyper_6_37_chunk_space2_time_idx on _hyper_6_37_chunk + -> Index Scan using _hyper_6_35_chunk_space2_time_idx on _hyper_6_35_chunk + -> Index Scan using _hyper_6_33_chunk_space2_time_idx on _hyper_6_33_chunk + -> Index Scan using _hyper_6_31_chunk_space2_time_idx on _hyper_6_31_chunk + -> Index Scan using _hyper_6_29_chunk_space2_time_idx on _hyper_6_29_chunk + -> Index Scan using _hyper_6_27_chunk_space2_time_idx on _hyper_6_27_chunk + -> Index Scan using _hyper_6_25_chunk_space2_time_idx on _hyper_6_25_chunk + -> Index Scan using _hyper_6_23_chunk_space2_time_idx on _hyper_6_23_chunk + -> Index Scan using _hyper_6_21_chunk_space2_time_idx on _hyper_6_21_chunk (24 rows) -- test hypertable with 3 space dimensions @@ -1215,781 +558,48 @@ ORDER BY time DESC; Custom Scan (ChunkAppend) on space3 Order: space3."time" DESC -> Merge Append - Sort Key: _hyper_9_63_chunk."time" DESC - -> Index Only Scan using _hyper_9_63_chunk_space3_time_idx on _hyper_9_63_chunk - -> Index Only Scan using _hyper_9_61_chunk_space3_time_idx on _hyper_9_61_chunk - -> Index Only Scan using _hyper_9_59_chunk_space3_time_idx on _hyper_9_59_chunk - -> Index Only Scan using _hyper_9_57_chunk_space3_time_idx on _hyper_9_57_chunk - -> Index Only Scan using _hyper_9_55_chunk_space3_time_idx on _hyper_9_55_chunk - -> Index Only Scan using _hyper_9_53_chunk_space3_time_idx on _hyper_9_53_chunk - -> Index Only Scan using _hyper_9_51_chunk_space3_time_idx on _hyper_9_51_chunk - -> Index Only Scan using _hyper_9_49_chunk_space3_time_idx on _hyper_9_49_chunk + Sort Key: _hyper_7_52_chunk."time" DESC + -> Index Only Scan using _hyper_7_52_chunk_space3_time_idx on _hyper_7_52_chunk + -> Index Only Scan using _hyper_7_50_chunk_space3_time_idx on _hyper_7_50_chunk + -> Index Only Scan using _hyper_7_48_chunk_space3_time_idx on _hyper_7_48_chunk + -> Index Only Scan using _hyper_7_46_chunk_space3_time_idx on _hyper_7_46_chunk + -> Index Only Scan using _hyper_7_44_chunk_space3_time_idx on _hyper_7_44_chunk + -> Index Only Scan using _hyper_7_42_chunk_space3_time_idx on _hyper_7_42_chunk + -> Index Only Scan using _hyper_7_40_chunk_space3_time_idx on _hyper_7_40_chunk + -> Index Only Scan using _hyper_7_38_chunk_space3_time_idx on _hyper_7_38_chunk -> Merge Append - Sort Key: _hyper_9_64_chunk."time" DESC - -> Index Only Scan using _hyper_9_64_chunk_space3_time_idx on _hyper_9_64_chunk - -> Index Only Scan using _hyper_9_62_chunk_space3_time_idx on _hyper_9_62_chunk - -> Index Only Scan using _hyper_9_60_chunk_space3_time_idx on _hyper_9_60_chunk - -> Index Only Scan using _hyper_9_58_chunk_space3_time_idx on _hyper_9_58_chunk - -> Index Only Scan using _hyper_9_56_chunk_space3_time_idx on _hyper_9_56_chunk - -> Index Only Scan using _hyper_9_54_chunk_space3_time_idx on _hyper_9_54_chunk - -> Index Only Scan using _hyper_9_52_chunk_space3_time_idx on _hyper_9_52_chunk - -> Index Only Scan using _hyper_9_50_chunk_space3_time_idx on _hyper_9_50_chunk + Sort Key: _hyper_7_53_chunk."time" DESC + -> Index Only Scan using _hyper_7_53_chunk_space3_time_idx on _hyper_7_53_chunk + -> Index Only Scan using _hyper_7_51_chunk_space3_time_idx on _hyper_7_51_chunk + -> Index Only Scan using _hyper_7_49_chunk_space3_time_idx on _hyper_7_49_chunk + -> Index Only Scan using _hyper_7_47_chunk_space3_time_idx on _hyper_7_47_chunk + -> Index Only Scan using _hyper_7_45_chunk_space3_time_idx on _hyper_7_45_chunk + -> Index Only Scan using _hyper_7_43_chunk_space3_time_idx on _hyper_7_43_chunk + -> Index Only Scan using _hyper_7_41_chunk_space3_time_idx on _hyper_7_41_chunk + -> Index Only Scan using _hyper_7_39_chunk_space3_time_idx on _hyper_7_39_chunk (22 rows) --- expressions in ORDER BY clause -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 LIMIT 10; - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on space - Order: time_bucket('@ 1 hour'::interval, space."time") - -> Merge Append - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_24_chunk."time")) - -> Index Only Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk - -> Index Only Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk - -> Index Only Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk - -> Index Only Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk - -> Merge Append - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_23_chunk."time")) - -> Index Only Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk - -> Index Only Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk - -> Index Only Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk - -> Index Only Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk -(15 rows) - -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 DESC LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------ - Limit - -> Custom Scan (ChunkAppend) on space - Order: time_bucket('@ 1 hour'::interval, space."time") DESC - -> Merge Append - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_29_chunk."time")) DESC - -> Index Only Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk - -> Index Only Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk - -> Index Only Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk - -> Index Only Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk - -> Merge Append - Sort Key: (time_bucket('@ 1 hour'::interval, _hyper_7_30_chunk."time")) DESC - -> Index Only Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk - -> Index Only Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk - -> Index Only Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk - -> Index Only Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk -(15 rows) - --- test LATERAL with correlated query --- only last chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Nested Loop Left Join - -> Function Scan on generate_series g - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append o - Order: o."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_1 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_3 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(12 rows) - --- test LATERAL with correlated query --- only 2nd chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 -) l ON true; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Nested Loop Left Join - -> Function Scan on generate_series g - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append o - Order: o."time" - Chunks excluded during startup: 0 - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_1 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_3 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(12 rows) - --- test startup and runtime exclusion together -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join - -> Function Scan on generate_series g - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append o - Order: o."time" DESC - Chunks excluded during startup: 0 - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o_1 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o_2 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o_3 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) -(12 rows) - --- test startup and runtime exclusion together --- all chunks should be filtered -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------ - Nested Loop Left Join - -> Function Scan on generate_series g - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append o - Order: o."time" DESC - Chunks excluded during startup: 3 -(6 rows) - --- test CTE --- no chunk exclusion for CTE because cte query is not pulled up -:PREFIX WITH cte AS (SELECT * FROM ordered_append ORDER BY time) -SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - CTE Scan on cte - Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - CTE cte - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(8 rows) - --- test JOIN --- no exclusion on joined table because quals are not propagated yet -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN ordered_append o2 ON o1.time = o2.time -WHERE o1.time < '2000-02-01' -ORDER BY o1.time; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 - Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) -(19 rows) - --- test JOIN --- last chunk of o2 should not be executed -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN (SELECT * FROM ordered_append o2 ORDER BY time) o2 ON o1.time = o2.time -WHERE o1.time < '2000-01-08' -ORDER BY o1.time; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test subquery --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append WHERE time = (SELECT max(time) FROM ordered_append) ORDER BY time; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Custom Scan (ChunkAppend) on ordered_append - InitPlan 2 (returns $1) - -> Result - InitPlan 1 (returns $0) - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append ordered_append_1 - Order: ordered_append_1."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk _hyper_1_3_chunk_1 - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk _hyper_1_2_chunk_1 - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk _hyper_1_1_chunk_1 - Index Cond: ("time" IS NOT NULL) - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" = $1) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" = $1) - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" = $1) -(19 rows) - --- test join against max query --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append o1 INNER JOIN (SELECT max(time) AS max_time FROM ordered_append) o2 ON o1.time = o2.max_time ORDER BY time; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Sort - Sort Key: o1."time" - -> Nested Loop - -> Result - InitPlan 1 (returns $0) - -> Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" DESC - -> Index Only Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - Index Cond: ("time" IS NOT NULL) - -> Index Only Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - Index Cond: ("time" IS NOT NULL) - -> Append - -> Index Scan using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1 - Index Cond: ("time" = ($0)) - -> Index Scan using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_1 - Index Cond: ("time" = ($0)) - -> Index Scan using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_2 - Index Cond: ("time" = ($0)) -(21 rows) - --- test ordered append with limit expression -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT (SELECT length('four')); - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - InitPlan 1 (returns $0) - -> Result - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(8 rows) - --- test with ordered guc disabled -SET timescaledb.enable_ordered_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Merge Append - Sort Key: _hyper_1_1_chunk."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - -RESET timescaledb.enable_ordered_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - --- test with chunk append disabled -SET timescaledb.enable_chunk_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Merge Append - Sort Key: _hyper_1_1_chunk."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - -RESET timescaledb.enable_chunk_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Limit - -> Custom Scan (ChunkAppend) on ordered_append - Order: ordered_append."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk -(6 rows) - --- test space partitioning with startup exclusion -:PREFIX SELECT * -FROM space WHERE time < now() ORDER BY time; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Custom Scan (ChunkAppend) on space - Order: space."time" - -> Merge Append - Sort Key: _hyper_7_24_chunk."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk - Index Cond: ("time" < now()) - -> Merge Append - Sort Key: _hyper_7_23_chunk."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk - Index Cond: ("time" < now()) - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk - Index Cond: ("time" < now()) -(22 rows) - --- test runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Nested Loop Left Join - -> Function Scan on generate_series g - -> Limit - -> Custom Scan (ChunkAppend) on space o - Order: o."time" DESC - -> Merge Append - Sort Key: o_1."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk o_1 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk o_2 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk o_3 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk o_4 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Merge Append - Sort Key: o_5."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk o_5 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk o_6 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk o_7 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk o_8 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) -(25 rows) - --- test startup and runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Nested Loop Left Join - -> Function Scan on generate_series g - -> Limit - -> Custom Scan (ChunkAppend) on space o - Order: o."time" DESC - -> Merge Append - Sort Key: o_1."time" DESC - -> Index Scan using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk o_1 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk o_2 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk o_3 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk o_4 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Merge Append - Sort Key: o_5."time" DESC - -> Index Scan using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk o_5 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk o_6 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk o_7 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) - -> Index Scan using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk o_8 - Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) -(25 rows) - --- test JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test JOIN on time column with USING --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 USING(time) ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test NATURAL JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 NATURAL INNER JOIN ordered_append o2 ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - Join Filter: ((o1.device_id = o2.device_id) AND (o1.value = o2.value)) - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(15 rows) - --- test LEFT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 LEFT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Left Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test RIGHT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 RIGHT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Left Join - Merge Cond: (o2."time" = o1."time") - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 -(14 rows) - --- test JOIN on time column with ON clause expression order switched --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test JOIN on time column with equality condition in WHERE clause --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test JOIN on time column with ORDER BY 2nd hypertable --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test JOIN on time column and device_id --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - Join Filter: (o1.device_id = o2.device_id) - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(15 rows) - --- test JOIN on device_id --- should not use ordered append for 2nd hypertable -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id ORDER BY o1.time LIMIT 100; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Limit - -> Nested Loop - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Append - -> Index Scan using _hyper_1_1_chunk_ordered_append_device_id_time_idx on _hyper_1_1_chunk o2 - Index Cond: (device_id = o1.device_id) - -> Index Scan using _hyper_1_2_chunk_ordered_append_device_id_time_idx on _hyper_1_2_chunk o2_1 - Index Cond: (device_id = o1.device_id) - -> Index Scan using _hyper_1_3_chunk_ordered_append_device_id_time_idx on _hyper_1_3_chunk o2_2 - Index Cond: (device_id = o1.device_id) -(14 rows) - --- test JOIN on time column with implicit join --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1, ordered_append o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(14 rows) - --- test JOIN on time column with 3 hypertables --- should use 3 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time INNER JOIN ordered_append o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (o3."time" = o1."time") - -> Custom Scan (ChunkAppend) on ordered_append o3 - Order: o3."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o3_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o3_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o3_3 - -> Materialize - -> Merge Join - Merge Cond: (o1."time" = o2."time") - -> Custom Scan (ChunkAppend) on ordered_append o1 - Order: o1."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o1_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o1_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o1_3 - -> Materialize - -> Custom Scan (ChunkAppend) on ordered_append o2 - Order: o2."time" - -> Index Scan Backward using _hyper_1_1_chunk_ordered_append_time_idx on _hyper_1_1_chunk o2_1 - -> Index Scan Backward using _hyper_1_2_chunk_ordered_append_time_idx on _hyper_1_2_chunk o2_2 - -> Index Scan Backward using _hyper_1_3_chunk_ordered_append_time_idx on _hyper_1_3_chunk o2_3 -(22 rows) - --- test with space partitioning -:PREFIX SELECT * FROM space s1 INNER JOIN space s2 ON s1.time = s2.time ORDER BY s1.time LIMIT 100; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (s1."time" = s2."time") - -> Custom Scan (ChunkAppend) on space s1 - Order: s1."time" - -> Merge Append - Sort Key: s1_1."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk s1_1 - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk s1_2 - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk s1_3 - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk s1_4 - -> Merge Append - Sort Key: s1_5."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk s1_5 - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk s1_6 - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk s1_7 - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk s1_8 - -> Materialize - -> Custom Scan (ChunkAppend) on space s2 - Order: s2."time" - -> Merge Append - Sort Key: s2_1."time" - -> Index Scan Backward using _hyper_7_24_chunk_space_time_idx on _hyper_7_24_chunk s2_1 - -> Index Scan Backward using _hyper_7_26_chunk_space_time_idx on _hyper_7_26_chunk s2_2 - -> Index Scan Backward using _hyper_7_28_chunk_space_time_idx on _hyper_7_28_chunk s2_3 - -> Index Scan Backward using _hyper_7_30_chunk_space_time_idx on _hyper_7_30_chunk s2_4 - -> Merge Append - Sort Key: s2_5."time" - -> Index Scan Backward using _hyper_7_23_chunk_space_time_idx on _hyper_7_23_chunk s2_5 - -> Index Scan Backward using _hyper_7_25_chunk_space_time_idx on _hyper_7_25_chunk s2_6 - -> Index Scan Backward using _hyper_7_27_chunk_space_time_idx on _hyper_7_27_chunk s2_7 - -> Index Scan Backward using _hyper_7_29_chunk_space_time_idx on _hyper_7_29_chunk s2_8 -(32 rows) - -- test COLLATION -- cant be tested in our ci because alpine doesnt support locales -- :PREFIX SELECT * FROM sortopt_test ORDER BY time, device COLLATE "en_US.utf8"; -- test NULLS FIRST :PREFIX SELECT * FROM sortopt_test ORDER BY time, device NULLS FIRST; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Custom Scan (ChunkAppend) on sortopt_test Order: sortopt_test."time", sortopt_test.device NULLS FIRST - -> Index Only Scan using _hyper_10_66_chunk_time_device_nullsfirst on _hyper_10_66_chunk - -> Index Only Scan using _hyper_10_65_chunk_time_device_nullsfirst on _hyper_10_65_chunk + -> Index Only Scan using _hyper_8_55_chunk_time_device_nullsfirst on _hyper_8_55_chunk + -> Index Only Scan using _hyper_8_54_chunk_time_device_nullsfirst on _hyper_8_54_chunk (4 rows) -- test NULLS LAST :PREFIX SELECT * FROM sortopt_test ORDER BY time, device DESC NULLS LAST; - QUERY PLAN --------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------ Custom Scan (ChunkAppend) on sortopt_test Order: sortopt_test."time", sortopt_test.device DESC NULLS LAST - -> Index Only Scan using _hyper_10_66_chunk_time_device_nullslast on _hyper_10_66_chunk - -> Index Only Scan using _hyper_10_65_chunk_time_device_nullslast on _hyper_10_65_chunk + -> Index Only Scan using _hyper_8_55_chunk_time_device_nullslast on _hyper_8_55_chunk + -> Index Only Scan using _hyper_8_54_chunk_time_device_nullslast on _hyper_8_54_chunk (4 rows) --generate the results into two different files diff --git a/test/runner_shared.sh b/test/runner_shared.sh new file mode 100755 index 000000000..c70b4cbbc --- /dev/null +++ b/test/runner_shared.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -u +set -e +CURRENT_DIR=$(dirname $0) +EXE_DIR=${EXE_DIR:-${CURRENT_DIR}} +PG_REGRESS_PSQL=$1 +PSQL=${PSQL:-$PG_REGRESS_PSQL} +PSQL="${PSQL} -X" # Prevent any .psqlrc files from being executed during the tests +TEST_PGUSER=${TEST_PGUSER:-postgres} +TEST_INPUT_DIR=${TEST_INPUT_DIR:-${EXE_DIR}} +TEST_OUTPUT_DIR=${TEST_OUTPUT_DIR:-${EXE_DIR}} + +#docker doesn't set user +USER=${USER:-`whoami`} + +TEST_SPINWAIT_ITERS=${TEST_SPINWAIT_ITERS:-10} + +TEST_ROLE_SUPERUSER=${TEST_ROLE_SUPERUSER:-super_user} +TEST_ROLE_DEFAULT_PERM_USER=${TEST_ROLE_DEFAULT_PERM_USER:-default_perm_user} +TEST_ROLE_DEFAULT_PERM_USER_2=${TEST_ROLE_DEFAULT_PERM_USER_2:-default_perm_user_2} + +shift + +# setup clusterwide settings on first run +if [[ ! -f ${TEST_OUTPUT_DIR}/.pg_init ]]; then + touch ${TEST_OUTPUT_DIR}/.pg_init + ${PSQL} $@ -U ${USER} -d postgres -v ECHO=none -c "ALTER USER ${TEST_ROLE_SUPERUSER} WITH SUPERUSER;" >/dev/null + ${PSQL} $@ -U $TEST_PGUSER -d ${TEST_DBNAME} -v ECHO=none < ${TEST_INPUT_DIR}/shared/sql/include/shared_setup.sql >/dev/null +fi + +cd ${EXE_DIR}/sql + +# we strip out any output between +# and the part about memory usage in EXPLAIN ANALYZE output of Sort nodes +${PSQL} -U ${TEST_PGUSER} \ + -v ON_ERROR_STOP=1 \ + -v VERBOSITY=terse \ + -v ECHO=all \ + -v TEST_INPUT_DIR=${TEST_INPUT_DIR} \ + -v TEST_OUTPUT_DIR=${TEST_OUTPUT_DIR} \ + -v TEST_SPINWAIT_ITERS=${TEST_SPINWAIT_ITERS} \ + -v ROLE_SUPERUSER=${TEST_ROLE_SUPERUSER} \ + -v ROLE_DEFAULT_PERM_USER=${TEST_ROLE_DEFAULT_PERM_USER} \ + -v ROLE_DEFAULT_PERM_USER_2=${TEST_ROLE_DEFAULT_PERM_USER_2} \ + $@ -d ${TEST_DBNAME} 2>&1 | sed -e '//,/<\/exclude_from_test>/d' -e 's! Memory: [0-9]\{1,\}kB!!' -e 's! Memory Usage: [0-9]\{1,\}kB!!' diff --git a/test/sql/CMakeLists.txt b/test/sql/CMakeLists.txt index 51665e4ca..4a6813338 100644 --- a/test/sql/CMakeLists.txt +++ b/test/sql/CMakeLists.txt @@ -144,11 +144,6 @@ set(TEST_TEMPLATES # be in the same directory. These files are updated when the template # is edited, but not when the output file is deleted. If the output is # deleted either recreate it manually, or rerun cmake on the root dir. -if (${PG_VERSION_MAJOR} GREATER "9") - set(TEST_VERSION_SUFFIX ${PG_VERSION_MAJOR}) -else () - set(TEST_VERSION_SUFFIX ${PG_VERSION_MAJOR}.${PG_VERSION_MINOR}) -endif () foreach(TEMPLATE_FILE ${TEST_TEMPLATES}) string(LENGTH ${TEMPLATE_FILE} TEMPLATE_NAME_LEN) math(EXPR TEMPLATE_NAME_LEN ${TEMPLATE_NAME_LEN}-7) diff --git a/test/sql/include/plan_ordered_append_load.sql b/test/sql/include/plan_ordered_append_load.sql index c958154d4..b1f9d345f 100644 --- a/test/sql/include/plan_ordered_append_load.sql +++ b/test/sql/include/plan_ordered_append_load.sql @@ -18,16 +18,6 @@ INSERT INTO devices VALUES (2,'Device 2'), (3,'Device 3'); --- create a table where we create chunks in order -CREATE TABLE ordered_append(time timestamptz NOT NULL, device_id INT, value float); -SELECT create_hypertable('ordered_append','time'); -CREATE index on ordered_append(time DESC,device_id); -CREATE index on ordered_append(device_id,time DESC); - -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 1, 0.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 2, 1.5; -INSERT INTO ordered_append SELECT generate_series('2000-01-01'::timestamptz,'2000-01-18'::timestamptz,'1m'::interval), 3, 2.5; - -- create a second table where we create chunks in reverse order CREATE TABLE ordered_append_reverse(time timestamptz NOT NULL, device_id INT, value float); SELECT create_hypertable('ordered_append_reverse','time'); @@ -60,7 +50,6 @@ INSERT INTO dimension_only VALUES ('2000-01-07'); ANALYZE devices; -ANALYZE ordered_append; ANALYZE ordered_append_reverse; ANALYZE dimension_last; ANALYZE dimension_only; @@ -104,18 +93,6 @@ INSERT INTO ht_dropped_columns(time,device_id,value) SELECT generate_series('200 ANALYZE ht_dropped_columns; -CREATE TABLE space(time timestamptz NOT NULL, device_id int NOT NULL, value float); -SELECT create_hypertable('space','time','device_id',number_partitions:=4); - -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 1, 1.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 2, 2.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 3, 3.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 4, 4.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 5, 5.5; -INSERT INTO space SELECT generate_series('2000-01-10'::timestamptz,'2000-01-01'::timestamptz,'-1m'::interval), 6, 6.5; - -ANALYZE space; - CREATE TABLE space2(time timestamptz NOT NULL, device_id int NOT NULL, tag_id int NOT NULL, value float); SELECT create_hypertable('space2','time','device_id',number_partitions:=3); SELECT add_dimension('space2','tag_id',number_partitions:=3); diff --git a/test/sql/include/plan_ordered_append_query.sql b/test/sql/include/plan_ordered_append_query.sql index e352af2d8..5647fc160 100644 --- a/test/sql/include/plan_ordered_append_query.sql +++ b/test/sql/include/plan_ordered_append_query.sql @@ -15,18 +15,6 @@ FROM INNER JOIN _timescaledb_catalog.hypertable ht ON d.hypertable_id = ht.id ORDER BY ht.table_name, range_start, chunk; --- test ASC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - --- test DESC for ordered chunks -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC LIMIT 1; - -- test ASC for reverse ordered chunks :PREFIX SELECT time, device_id, value @@ -39,121 +27,6 @@ ORDER BY time ASC LIMIT 1; FROM ordered_append_reverse ORDER BY time DESC LIMIT 1; --- test query with ORDER BY column not in targetlist -:PREFIX SELECT - device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - --- ORDER BY may include other columns after time column -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - --- test RECORD in targetlist -:PREFIX SELECT - (time, device_id, value) -FROM ordered_append -ORDER BY time DESC, device_id LIMIT 1; - --- test sort column not in targetlist -:PREFIX SELECT - time_bucket('1h',time) -FROM ordered_append -ORDER BY time DESC LIMIT 1; - --- queries with ORDER BY non-time column shouldn't use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id LIMIT 1; - --- time column must be primary sort order -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY device_id, time LIMIT 1; - --- queries without LIMIT should use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -ORDER BY time ASC; - --- queries without ORDER BY shouldnt use ordered append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -LIMIT 1; - --- test interaction with constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > '2000-01-07' -ORDER BY time DESC LIMIT 1; - --- test interaction with constraint aware append -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() -ORDER BY time ASC LIMIT 1; - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() -ORDER BY time ASC LIMIT 1; - --- test constraint exclusion -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time > now_s() AND time < '2000-01-10' -ORDER BY time ASC LIMIT 1; - -:PREFIX SELECT - time, device_id, value -FROM ordered_append -WHERE time < now_s() AND time > '2000-01-07' -ORDER BY time ASC LIMIT 1; - --- min/max queries -:PREFIX SELECT max(time) FROM ordered_append; - -:PREFIX SELECT min(time) FROM ordered_append; - --- test first/last (doesn't use ordered append yet) -:PREFIX SELECT first(time, time) FROM ordered_append; - -:PREFIX SELECT last(time, time) FROM ordered_append; - --- test query with time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time ASC LIMIT 1; - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - --- test query with ORDER BY time_bucket -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY time_bucket('1d',time) LIMIT 1; - -- test query with ORDER BY time_bucket, device_id -- must not use ordered append :PREFIX SELECT @@ -161,18 +34,6 @@ ORDER BY time_bucket('1d',time) LIMIT 1; FROM dimension_last ORDER BY time_bucket('1d',time), device_id LIMIT 1; --- test query with ORDER BY date_trunc -:PREFIX SELECT - time_bucket('1d',time), device_id, value -FROM ordered_append -ORDER BY date_trunc('day', time) LIMIT 1; - --- test query with ORDER BY date_trunc -:PREFIX SELECT - date_trunc('day',time), device_id, value -FROM ordered_append -ORDER BY 1 LIMIT 1; - -- test query with ORDER BY date_trunc, device_id -- must not use ordered append :PREFIX SELECT @@ -180,28 +41,6 @@ ORDER BY 1 LIMIT 1; FROM dimension_last ORDER BY 1,2 LIMIT 1; --- test query with now() should result in ordered ChunkAppend -:PREFIX SELECT * FROM ordered_append WHERE time < now() + '1 month' -ORDER BY time DESC limit 1; - --- test CTE -:PREFIX WITH i AS (SELECT * FROM ordered_append WHERE time < now() ORDER BY time DESC limit 100) -SELECT * FROM i; - --- test LATERAL with ordered append in the outer query -:PREFIX SELECT * FROM ordered_append, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; - --- test LATERAL with ordered append in the lateral query -:PREFIX SELECT * FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM ordered_append ORDER BY time DESC limit 2) l; - --- test plan with best index is chosen --- this should use device_id, time index -:PREFIX SELECT * FROM ordered_append WHERE device_id = 1 ORDER BY time DESC LIMIT 1; - --- test plan with best index is chosen --- this should use time index -:PREFIX SELECT * FROM ordered_append ORDER BY time DESC LIMIT 1; - -- test with table with only dimension column :PREFIX SELECT * FROM dimension_only ORDER BY time DESC LIMIT 1; @@ -261,48 +100,6 @@ FROM ht_dropped_columns WHERE device_id = 1 ORDER BY time DESC; --- test hypertable with space partitioning -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time; - --- test hypertable with space partitioning and exclusion in space --- should remove 3 of 4 space partitions (2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id = 1 -ORDER BY time; - --- test hypertable with space partitioning and exclusion in space --- should remove 2 of 4 space partitions (2 + 2 chunks scanned) -:PREFIX SELECT - time, device_id, value -FROM space -WHERE device_id IN (1, 4) -ORDER BY time; - --- test hypertable with space partitioning and reverse order -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time DESC; - --- test hypertable with space partitioning ORDER BY multiple columns --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY time, device_id LIMIT 1; - --- test hypertable with space partitioning ORDER BY non-time column --- does not use ordered append -:PREFIX SELECT - time, device_id, value -FROM space -ORDER BY device_id, time LIMIT 1; - -- test hypertable with 2 space dimensions :PREFIX SELECT time, device_id, value @@ -315,176 +112,6 @@ ORDER BY time DESC; FROM space3 ORDER BY time DESC; --- expressions in ORDER BY clause -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 LIMIT 10; - -:PREFIX SELECT - time_bucket('1h',time) -FROM space -ORDER BY 1 DESC LIMIT 10; - --- test LATERAL with correlated query --- only last chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - --- test LATERAL with correlated query --- only 2nd chunk should be executed -:PREFIX SELECT * -FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 -) l ON true; - --- test startup and runtime exclusion together -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - --- test startup and runtime exclusion together --- all chunks should be filtered -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM ordered_append o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 -) l ON true; - --- test CTE --- no chunk exclusion for CTE because cte query is not pulled up -:PREFIX WITH cte AS (SELECT * FROM ordered_append ORDER BY time) -SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; - --- test JOIN --- no exclusion on joined table because quals are not propagated yet -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN ordered_append o2 ON o1.time = o2.time -WHERE o1.time < '2000-02-01' -ORDER BY o1.time; - --- test JOIN --- last chunk of o2 should not be executed -:PREFIX SELECT * -FROM ordered_append o1 -INNER JOIN (SELECT * FROM ordered_append o2 ORDER BY time) o2 ON o1.time = o2.time -WHERE o1.time < '2000-01-08' -ORDER BY o1.time; - --- test subquery --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append WHERE time = (SELECT max(time) FROM ordered_append) ORDER BY time; - --- test join against max query --- not ChunkAppend so no chunk exclusion -:PREFIX SELECT * -FROM ordered_append o1 INNER JOIN (SELECT max(time) AS max_time FROM ordered_append) o2 ON o1.time = o2.max_time ORDER BY time; - --- test ordered append with limit expression -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT (SELECT length('four')); - --- test with ordered guc disabled -SET timescaledb.enable_ordered_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - -RESET timescaledb.enable_ordered_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - --- test with chunk append disabled -SET timescaledb.enable_chunk_append TO off; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - -RESET timescaledb.enable_chunk_append; -:PREFIX SELECT * -FROM ordered_append ORDER BY time LIMIT 3; - --- test space partitioning with startup exclusion -:PREFIX SELECT * -FROM space WHERE time < now() ORDER BY time; - --- test runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 -) l ON true; - --- test startup and runtime exclusion together with space partitioning -:PREFIX SELECT * -FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) -LEFT OUTER JOIN LATERAL( - SELECT * FROM space o - WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 -) l ON true; - --- test JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; - --- test JOIN on time column with USING --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 USING(time) ORDER BY o1.time LIMIT 100; - --- test NATURAL JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 NATURAL INNER JOIN ordered_append o2 ORDER BY o1.time LIMIT 100; - --- test LEFT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 LEFT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; - --- test RIGHT JOIN on time column --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 RIGHT JOIN ordered_append o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; - --- test JOIN on time column with ON clause expression order switched --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; - --- test JOIN on time column with equality condition in WHERE clause --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - --- test JOIN on time column with ORDER BY 2nd hypertable --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; - --- test JOIN on time column and device_id --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; - --- test JOIN on device_id --- should not use ordered append for 2nd hypertable -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.device_id = o2.device_id ORDER BY o1.time LIMIT 100; - --- test JOIN on time column with implicit join --- should use 2 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1, ordered_append o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; - --- test JOIN on time column with 3 hypertables --- should use 3 ChunkAppend -:PREFIX SELECT * FROM ordered_append o1 INNER JOIN ordered_append o2 ON o1.time = o2.time INNER JOIN ordered_append o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; - --- test with space partitioning -:PREFIX SELECT * FROM space s1 INNER JOIN space s2 ON s1.time = s2.time ORDER BY s1.time LIMIT 100; - -- test COLLATION -- cant be tested in our ci because alpine doesnt support locales -- :PREFIX SELECT * FROM sortopt_test ORDER BY time, device COLLATE "en_US.utf8"; diff --git a/test/test-defs.cmake b/test/test-defs.cmake index 142265b45..c2c4cf9b8 100644 --- a/test/test-defs.cmake +++ b/test/test-defs.cmake @@ -13,6 +13,7 @@ set(TEST_PGUSER ${TEST_ROLE_DEFAULT_PERM_USER} CACHE STRING "The PostgreSQL test set(TEST_DBNAME single CACHE STRING "The database name to use for tests") set(TEST_PGPORT_TEMP_INSTANCE 15432 CACHE STRING "The port to run a temporary test PostgreSQL instance on") set(TEST_SCHEDULE ${CMAKE_CURRENT_BINARY_DIR}/test_schedule) +set(TEST_SCHEDULE_SHARED ${CMAKE_CURRENT_BINARY_DIR}/shared/test_schedule_shared) set(ISOLATION_TEST_SCHEDULE ${CMAKE_CURRENT_BINARY_DIR}/isolation_test_schedule) set(PG_REGRESS_OPTS_BASE @@ -25,6 +26,11 @@ set(PG_REGRESS_OPTS_EXTRA --dbname=${TEST_DBNAME} --launcher=${PRIMARY_TEST_DIR}/runner.sh) +set(PG_REGRESS_SHARED_OPTS_EXTRA + --create-role=${TEST_ROLE_SUPERUSER},${TEST_ROLE_DEFAULT_PERM_USER},${TEST_ROLE_DEFAULT_PERM_USER_2} + --dbname=${TEST_DBNAME} + --launcher=${PRIMARY_TEST_DIR}/runner_shared.sh) + set(PG_ISOLATION_REGRESS_OPTS_EXTRA --create-role=${TEST_ROLE_SUPERUSER},${TEST_ROLE_DEFAULT_PERM_USER},${TEST_ROLE_DEFAULT_PERM_USER_2} --dbname=${TEST_DBNAME}) @@ -33,6 +39,11 @@ set(PG_REGRESS_OPTS_INOUT --inputdir=${TEST_INPUT_DIR} --outputdir=${TEST_OUTPUT_DIR}) +set(PG_REGRESS_SHARED_OPTS_INOUT + --inputdir=${TEST_INPUT_DIR}/shared + --outputdir=${TEST_OUTPUT_DIR}/shared + --load-extension=timescaledb) + set(PG_ISOLATION_REGRESS_OPTS_INOUT --inputdir=${TEST_INPUT_DIR}/isolation --outputdir=${TEST_OUTPUT_DIR}/isolation @@ -80,3 +91,10 @@ if(PG_ISOLATION_REGRESS) ISOLATION_TEST_SCHEDULE=${ISOLATION_TEST_SCHEDULE} PG_ISOLATION_REGRESS=${PG_ISOLATION_REGRESS}) endif() + +if (${PG_VERSION_MAJOR} GREATER "9") + set(TEST_VERSION_SUFFIX ${PG_VERSION_MAJOR}) +else () + set(TEST_VERSION_SUFFIX ${PG_VERSION_MAJOR}.${PG_VERSION_MINOR}) +endif () + diff --git a/tsl/test/CMakeLists.txt b/tsl/test/CMakeLists.txt index 417d12e4f..eb96009f0 100644 --- a/tsl/test/CMakeLists.txt +++ b/tsl/test/CMakeLists.txt @@ -30,6 +30,38 @@ if(PG_REGRESS) list(APPEND _local_install_checks regresschecklocal-t) list(APPEND _install_checks regresscheck-t) + + # shared tests also provide compressed hypertables which we do not support on 9.6 + if(${PG_VERSION_MAJOR} GREATER "9") + + add_custom_target(regresscheck-shared + COMMAND ${CMAKE_COMMAND} -E env + ${PG_REGRESS_ENV} + EXE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/shared + TEST_SCHEDULE=${TEST_SCHEDULE_SHARED} + ${PRIMARY_TEST_DIR}/pg_regress.sh + ${PG_REGRESS_OPTS_BASE} + ${PG_REGRESS_SHARED_OPTS_EXTRA} + ${PG_REGRESS_SHARED_OPTS_INOUT} + ${PG_REGRESS_OPTS_TEMP_INSTANCE} + USES_TERMINAL) + + add_custom_target(regresschecklocal-shared + COMMAND ${CMAKE_COMMAND} -E env + ${PG_REGRESS_ENV} + EXE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/shared + TEST_SCHEDULE=${TEST_SCHEDULE_SHARED} + ${PRIMARY_TEST_DIR}/pg_regress.sh + ${PG_REGRESS_OPTS_BASE} + ${PG_REGRESS_SHARED_OPTS_EXTRA} + ${PG_REGRESS_SHARED_OPTS_INOUT} + ${PG_REGRESS_OPTS_LOCAL_INSTANCE} + USES_TERMINAL) + + list(APPEND _install_checks regresscheck-shared) + list(APPEND _local_install_checks regresschecklocal-shared) + endif() + endif() if(PG_ISOLATION_REGRESS) @@ -61,13 +93,14 @@ if(PG_ISOLATION_REGRESS) list(APPEND _install_checks isolationcheck-t) endif() +add_subdirectory(shared) +add_subdirectory(sql) +add_subdirectory(isolation) + # installchecklocal tests against an existing postgres instance add_custom_target(installchecklocal-t DEPENDS ${_local_install_checks}) add_custom_target(installcheck-t DEPENDS ${_install_checks}) -add_subdirectory(sql) -add_subdirectory(isolation) - if (CMAKE_BUILD_TYPE MATCHES Debug) add_subdirectory(src) endif (CMAKE_BUILD_TYPE MATCHES Debug) diff --git a/tsl/test/isolation/specs/CMakeLists.txt b/tsl/test/isolation/specs/CMakeLists.txt index 0401dad21..a719bb010 100644 --- a/tsl/test/isolation/specs/CMakeLists.txt +++ b/tsl/test/isolation/specs/CMakeLists.txt @@ -1,20 +1,22 @@ set(TEST_FILES continuous_aggs_insert.spec - continuous_aggs_multi.spec) - -set(TEST_FILES_GT_9 - compression_ddl.spec) + continuous_aggs_multi.spec +) set(TEST_TEMPLATES reorder_deadlock.spec.in - reorder_vs_insert_other_chunk.spec.in) + reorder_vs_insert_other_chunk.spec.in +) set(TEST_TEMPLATES_DEBUG reorder_vs_insert.spec.in - reorder_vs_select.spec.in) + reorder_vs_select.spec.in +) if (${PG_VERSION_MAJOR} GREATER "9") - list( INSERT TEST_FILES 0 ${TEST_FILES_GT_9}) + list(APPEND TEST_FILES + compression_ddl.spec + ) endif () if (CMAKE_BUILD_TYPE MATCHES Debug) @@ -30,7 +32,9 @@ endforeach(TEMPLATE_FILE) file(REMOVE ${ISOLATION_TEST_SCHEDULE}) +list(SORT TEST_FILES) + foreach(TEST_FILE ${TEST_FILES}) - string(REGEX REPLACE "(.+)\.spec" "\\1" TESTS_TO_RUN ${TEST_FILE}) - file(APPEND ${ISOLATION_TEST_SCHEDULE} "test: ${TESTS_TO_RUN}\n") + string(REGEX REPLACE "(.+)\.spec" "\\1" TESTS_TO_RUN ${TEST_FILE}) + file(APPEND ${ISOLATION_TEST_SCHEDULE} "test: ${TESTS_TO_RUN}\n") endforeach(TEST_FILE) diff --git a/tsl/test/shared/CMakeLists.txt b/tsl/test/shared/CMakeLists.txt new file mode 100644 index 000000000..b8def8aa8 --- /dev/null +++ b/tsl/test/shared/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(sql) diff --git a/tsl/test/shared/expected/ordered_append-10.out b/tsl/test/shared/expected/ordered_append-10.out new file mode 100644 index 000000000..47a2ef1a1 --- /dev/null +++ b/tsl/test/shared/expected/ordered_append-10.out @@ -0,0 +1,7900 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. +\set TEST_BASE_NAME ordered_append +SELECT + format('include/%s_query.sql', :'TEST_BASE_NAME') as "TEST_QUERY_NAME", + format('%s/shared/results/%s_results_uncompressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED", + format('%s/shared/results/%s_results_uncompressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED_IDX", + format('%s/shared/results/%s_results_compressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED", + format('%s/shared/results/%s_results_compressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED_IDX" +\gset +SELECT format('\! diff -u --label "Uncompressed results" --label "Compressed results" %s %s', :'TEST_RESULTS_UNCOMPRESSED', :'TEST_RESULTS_COMPRESSED') as "DIFF_CMD" +\gset +-- get EXPLAIN output for all variations +-- look at postgres version to decide whether we run with analyze or without +SELECT + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off)' + ELSE 'EXPLAIN (costs off)' + END AS "PREFIX", + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off, verbose)' + ELSE 'EXPLAIN (costs off, verbose)' + END AS "PREFIX_VERBOSE" +\gset +set work_mem to '64MB'; +set max_parallel_workers_per_gather to 0; +\set TEST_TABLE 'metrics' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) +(6 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_1_3_chunk."time" DESC, _hyper_1_3_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) +(8 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_1_3_chunk."time" DESC, _hyper_1_3_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) +(9 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + -> Index Only Scan using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(9 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk.device_id, _hyper_1_1_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) +(8 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk (actual rows=10 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 10 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 +(12 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Custom Scan (ChunkAppend) on metrics (actual rows=68370 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=17990 loops=1) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 +(8 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_2_chunk (never executed) + -> Seq Scan on _hyper_1_3_chunk (never executed) +(6 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(9 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(9 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(10 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(10 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 +(7 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 +(7 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(14 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(14 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(15 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk."time" DESC + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(15 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics."time") + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk."time")), _hyper_1_1_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) +(9 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics."time") + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics."time") + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) +(6 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_1_1_chunk."time")), _hyper_1_1_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) +(9 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + Chunks excluded during startup: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 +(13 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=100 loops=1) + Order: metrics."time" DESC + Chunks excluded during startup: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=100 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 100 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 +(15 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Nested Loop (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=2 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) +(12 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=2 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(13 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 +(12 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=1 loops=3) + Order: o."time" DESC + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o_1 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o_2 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 +(16 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=1 loops=2) + Order: o."time" + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o_1 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o_2 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o_3 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 +(16 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=1 loops=3) + Order: o."time" DESC + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o_1 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o_2 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 +(16 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +---------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=0 loops=3) + Order: o."time" DESC + Chunks excluded during startup: 3 +(6 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Custom Scan (ChunkAppend) on metrics (actual rows=68370 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=17990 loops=1) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 +(11 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=68370 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=17990 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 + -> Materialize (actual rows=341846 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=68370 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=17990 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 +(25 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=2 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=2 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 2 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Materialize (actual rows=10 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=6 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=6 loops=1) + Heap Fetches: 6 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on metrics (actual rows=5 loops=1) + Chunks excluded during runtime: 2 + InitPlan 2 (returns $1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics metrics_1 (actual rows=1 loops=1) + Order: metrics_1."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk _hyper_1_3_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk _hyper_1_2_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk _hyper_1_1_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=5 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 5 +(26 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Nested Loop (actual rows=5 loops=1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Append (actual rows=5 loops=1) + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_2 (actual rows=5 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 5 +(28 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=4 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(11 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(9 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=3 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(9 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=3 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=0 loops=1) + Hash Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id) AND (o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + -> Append (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_1_chunk o1 (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_2_chunk o1_1 (never executed) + -> Seq Scan on _hyper_1_3_chunk o1_2 (never executed) + -> Hash (actual rows=0 loops=1) + Buckets: 131072 Batches: 1 + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk o2_2 (actual rows=25190 loops=1) +(16 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=20 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=21 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + Join Filter: (o1.device_id = o2.device_id) + Rows Removed by Join Filter: 400 + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=100 loops=1) + Order: o1."time" + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=100 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + -> Materialize (actual rows=500 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=101 loops=1) + Order: o2."time" + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=101 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) +(16 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=1 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk o1_1 (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Append (actual rows=100 loops=1) + -> Index Only Scan using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk o2 (actual rows=100 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 100 + -> Index Only Scan using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk o2_1 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk o2_2 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 +(24 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o3."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics o3 (actual rows=4 loops=1) + Order: o3."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o3_1 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o3_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o3_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Merge Join (actual rows=26 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=6 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=6 loops=1) + Heap Fetches: 6 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=26 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=6 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=6 loops=1) + Heap Fetches: 6 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(31 rows) + +\set TEST_TABLE 'metrics_space' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) +(18 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC, _hyper_2_12_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) +(14 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC, _hyper_2_12_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) +(15 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_device_id_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_device_id_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_device_id_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_device_id_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_device_id_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_device_id_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_device_id_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_device_id_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk.device_id, _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_device_id_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_device_id_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_device_id_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_device_id_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_device_id_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_device_id_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_device_id_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_device_id_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_2_10_chunk."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=10 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) +(9 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on metrics_space (actual rows=68370 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=10794 loops=1) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 +(26 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_5_chunk (never executed) + -> Seq Scan on _hyper_2_6_chunk (never executed) + -> Seq Scan on _hyper_2_7_chunk (never executed) + -> Seq Scan on _hyper_2_8_chunk (never executed) + -> Seq Scan on _hyper_2_9_chunk (never executed) + -> Seq Scan on _hyper_2_10_chunk (never executed) + -> Seq Scan on _hyper_2_11_chunk (never executed) + -> Seq Scan on _hyper_2_12_chunk (never executed) +(12 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(25 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(25 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=0 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=0 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=0 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=0 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(36 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(36 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=0 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=0 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=0 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=0 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 +(25 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 +(25 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------ + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(38 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(38 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(33 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------ + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(33 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_space."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_4_chunk."time")) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_7_chunk."time")) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_10_chunk."time")) + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) +(15 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_7_chunk."time")) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_10_chunk."time")) + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")) + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_7_chunk."time")) + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_10_chunk."time")) + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) +(18 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) +(15 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 +(36 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=100 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=100 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=21 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=60 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 60 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=21 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 21 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 +(38 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Nested Loop (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=2 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) +(30 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=2 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=2 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(31 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Index Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Filter: (device_id = 1) +(9 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=1 loops=3) + Order: o."time" DESC + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_1 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_2 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_3 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_4."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_4 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_6 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=3) + Sort Key: o_7."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_7 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_8 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_9 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 +(38 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=1 loops=2) + Order: o."time" + -> Merge Append (actual rows=0 loops=2) + Sort Key: o_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_1 (actual rows=0 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_2 (actual rows=0 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_3 (actual rows=0 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=2) + Sort Key: o_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_4 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_6 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_7 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_8 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_9 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 +(38 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=1 loops=3) + Order: o."time" DESC + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_1 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_2 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_3 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_4."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_4 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_6 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=3) + Sort Key: o_7."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_7 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_8 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_9 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 +(38 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=0 loops=3) + Order: o."time" DESC + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_1 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_2 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_3 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_4."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_4 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_6 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_7."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_7 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_8 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_9 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 +(38 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=68370 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=10794 loops=1) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 +(29 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=68370 loops=1) + Order: o1."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=10794 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Materialize (actual rows=341846 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=68370 loops=1) + Order: o2."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=10794 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 +(73 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=2 loops=1) + Order: o1."time" + -> Merge Append (actual rows=2 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=2 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=1 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=1 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Materialize (actual rows=10 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=6 loops=1) + Order: o2."time" + -> Merge Append (actual rows=6 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(54 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on metrics_space (actual rows=5 loops=1) + InitPlan 2 (returns $1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space metrics_space_1 (actual rows=1 loops=1) + Order: metrics_space_1."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk _hyper_2_12_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk _hyper_2_11_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk _hyper_2_10_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk _hyper_2_9_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk _hyper_2_8_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk _hyper_2_7_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk _hyper_2_6_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk _hyper_2_5_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk _hyper_2_4_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=1) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=1) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Merge Append (actual rows=5 loops=1) + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=3 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 1 +(70 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Nested Loop (actual rows=5 loops=1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Append (actual rows=5 loops=1) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_2 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_3 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_4 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_5 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_6 (actual rows=1 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_7 (actual rows=3 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_8 (actual rows=1 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 1 +(70 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=4 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=4 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(29 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=3 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=3 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Merge Join (actual rows=0 loops=1) + Merge Cond: ((o1.device_id = o2.device_id) AND (o1."time" = o2."time")) + Join Filter: ((o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + Rows Removed by Join Filter: 68370 + -> Merge Append (actual rows=68370 loops=1) + Sort Key: o1.device_id, o1."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_device_id_time_idx on _hyper_2_4_chunk o1 (actual rows=3598 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_device_id_time_idx on _hyper_2_5_chunk o1_1 (actual rows=10794 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_device_id_time_idx on _hyper_2_6_chunk o1_2 (actual rows=3598 loops=1) + -> Index Scan using _hyper_2_7_chunk_metrics_space_device_id_time_idx on _hyper_2_7_chunk o1_3 (actual rows=5038 loops=1) + -> Index Scan using _hyper_2_8_chunk_metrics_space_device_id_time_idx on _hyper_2_8_chunk o1_4 (actual rows=15114 loops=1) + -> Index Scan using _hyper_2_9_chunk_metrics_space_device_id_time_idx on _hyper_2_9_chunk o1_5 (actual rows=5038 loops=1) + -> Index Scan using _hyper_2_10_chunk_metrics_space_device_id_time_idx on _hyper_2_10_chunk o1_6 (actual rows=5038 loops=1) + -> Index Scan using _hyper_2_11_chunk_metrics_space_device_id_time_idx on _hyper_2_11_chunk o1_7 (actual rows=15114 loops=1) + -> Index Scan using _hyper_2_12_chunk_metrics_space_device_id_time_idx on _hyper_2_12_chunk o1_8 (actual rows=5038 loops=1) + -> Materialize (actual rows=68370 loops=1) + -> Merge Append (actual rows=68370 loops=1) + Sort Key: o2.device_id, o2."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_device_id_time_idx on _hyper_2_4_chunk o2 (actual rows=3598 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_device_id_time_idx on _hyper_2_5_chunk o2_1 (actual rows=10794 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_device_id_time_idx on _hyper_2_6_chunk o2_2 (actual rows=3598 loops=1) + -> Index Scan using _hyper_2_7_chunk_metrics_space_device_id_time_idx on _hyper_2_7_chunk o2_3 (actual rows=5038 loops=1) + -> Index Scan using _hyper_2_8_chunk_metrics_space_device_id_time_idx on _hyper_2_8_chunk o2_4 (actual rows=15114 loops=1) + -> Index Scan using _hyper_2_9_chunk_metrics_space_device_id_time_idx on _hyper_2_9_chunk o2_5 (actual rows=5038 loops=1) + -> Index Scan using _hyper_2_10_chunk_metrics_space_device_id_time_idx on _hyper_2_10_chunk o2_6 (actual rows=5038 loops=1) + -> Index Scan using _hyper_2_11_chunk_metrics_space_device_id_time_idx on _hyper_2_11_chunk o2_7 (actual rows=15114 loops=1) + -> Index Scan using _hyper_2_12_chunk_metrics_space_device_id_time_idx on _hyper_2_12_chunk o2_8 (actual rows=5038 loops=1) +(31 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=20 loops=1) + Order: o2."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=21 loops=1) + Order: o1."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + Join Filter: (o1.device_id = o2.device_id) + Rows Removed by Join Filter: 400 + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=100 loops=1) + Order: o1."time" + -> Merge Append (actual rows=100 loops=1) + Sort Key: o1_1."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=21 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=60 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=21 loops=1) + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + -> Materialize (actual rows=500 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=101 loops=1) + Order: o2."time" + -> Merge Append (actual rows=101 loops=1) + Sort Key: o2_1."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=21 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=61 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=21 loops=1) + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) +(40 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=1 loops=1) + Order: o1."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_2 (never executed) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_3 (never executed) + Filter: (device_id = 1) + -> Materialize (actual rows=100 loops=1) + -> Append (actual rows=100 loops=1) + -> Seq Scan on _hyper_2_10_chunk o2 (actual rows=100 loops=1) + Filter: (device_id = 1) + -> Seq Scan on _hyper_2_4_chunk o2_1 (never executed) + Filter: (device_id = 1) + -> Seq Scan on _hyper_2_7_chunk o2_2 (never executed) + Filter: (device_id = 1) +(18 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o3."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics_space o3 (actual rows=4 loops=1) + Order: o3."time" + -> Merge Append (actual rows=4 loops=1) + Sort Key: o3_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o3_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o3_2 (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o3_3 (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: o3_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o3_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o3_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o3_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o3_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o3_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o3_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o3_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Merge Join (actual rows=26 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=6 loops=1) + Order: o1."time" + -> Merge Append (actual rows=6 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=26 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=6 loops=1) + Order: o2."time" + -> Merge Append (actual rows=6 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(85 rows) + +\set TEST_TABLE 'metrics_compressed' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(11 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC, _hyper_3_15_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(11 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC, _hyper_3_15_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(12 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(12 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_17_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_16_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(18 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk.device_id, _hyper_3_13_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk.device_id, compress_hyper_4_18_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_17_chunk.device_id, compress_hyper_4_17_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_16_chunk.device_id, compress_hyper_4_16_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(18 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_3_13_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=10 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk (actual rows=4 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_17_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk (actual rows=6 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Index Scan Backward using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) +(18 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Sort (actual rows=68370 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(10 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (never executed) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (never executed) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) +(9 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_14_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=20385 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 4615 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) +(15 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=20385 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 4615 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 +(15 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=41975 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=16785 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 8405 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(13 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=26390 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=8400 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 16790 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) +(13 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=7195 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=7195 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 12995 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 +(12 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=3595 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=3595 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 21405 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 +(12 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_3_13_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_3_13_chunk."time")), _hyper_3_13_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_3_13_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_3_13_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_3_13_chunk."time")), _hyper_3_13_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=68370 loops=1) + Chunks excluded during startup: 0 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(15 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: metrics_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=68370 loops=1) + Chunks excluded during startup: 0 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(17 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Nested Loop (actual rows=136740 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Append (actual rows=68370 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=2) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=2) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=2) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=2) +(13 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(16 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: metrics_compressed."time" DESC + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Index Scan using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_4_17_chunk._ts_meta_sequence_num + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_4_18_chunk._ts_meta_sequence_num + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk (never executed) + Index Cond: (device_id = 1) +(16 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(11 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=3600 loops=3) + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o_1 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o_2 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o_3 (actual rows=3600 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4063 + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=8 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 12 +(23 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Sort (actual rows=1 loops=2) + Sort Key: o."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=3600 loops=2) + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o_1 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_18_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o_2 (actual rows=3600 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 3900 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=8 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 22 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o_3 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) +(23 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=3600 loops=3) + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o_1 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o_2 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o_3 (actual rows=3600 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 4063 + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=8 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 12 +(23 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Sort (actual rows=0 loops=3) + Sort Key: o."time" DESC + Sort Method: quicksort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=0 loops=3) + Chunks excluded during startup: 3 +(8 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Sort (actual rows=68370 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(13 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=68370 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Sort (actual rows=341846 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) +(34 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=2 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=26390 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=8400 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1790 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 15 + -> Materialize (actual rows=10 loops=1) + -> Sort (actual rows=6 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(29 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Custom Scan (ChunkAppend) on metrics_compressed (actual rows=5 loops=1) + Chunks excluded during runtime: 1 + InitPlan 1 (returns $0) + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk _hyper_3_13_chunk_1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk _hyper_3_14_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk _hyper_3_15_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 20 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (never executed) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=5 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 4995 + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=5 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 25 +(26 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=5 loops=1) + Hash Cond: (o1."time" = (max(_hyper_3_13_chunk."time"))) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Hash (actual rows=1 loops=1) + Buckets: 1024 Batches: 1 + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(22 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(13 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=0 loops=1) + Hash Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id) AND (o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (never executed) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (never executed) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + -> Hash (actual rows=0 loops=1) + Buckets: 131072 Batches: 1 + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(22 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id)) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time", o1.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time", o2.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed o1 (actual rows=1 loops=1) + Order: o1."time" + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1_1 (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk (actual rows=4 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_2 (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_4_17_chunk._ts_meta_sequence_num DESC + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_3 (never executed) + -> Index Scan Backward using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk (never executed) + Index Cond: (device_id = 1) + -> Append (actual rows=100 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=100 loops=1) + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (never executed) + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (never executed) + -> Index Scan using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (never executed) + Index Cond: (device_id = 1) +(28 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + Join Filter: (o1."time" = o3."time") + Rows Removed by Join Filter: 1316920 + -> Merge Join (actual rows=20 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=4 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + -> Append (actual rows=65851 loops=20) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o3 (actual rows=17990 loops=20) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_2 (actual rows=20 loops=20) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o3_1 (actual rows=25190 loops=19) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_2 (actual rows=30 loops=19) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o3_2 (actual rows=25190 loops=19) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_2 (actual rows=30 loops=19) +(33 rows) + +\set TEST_TABLE 'metrics_space_compressed' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(23 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC, _hyper_5_27_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(23 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC, _hyper_5_27_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(24 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(24 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_35_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_34_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_33_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_32_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_31_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_29_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_28_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(48 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk.device_id, _hyper_5_19_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk.device_id, compress_hyper_6_36_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_35_chunk.device_id, compress_hyper_6_35_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_34_chunk.device_id, compress_hyper_6_34_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_33_chunk.device_id, compress_hyper_6_33_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_32_chunk.device_id, compress_hyper_6_32_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_31_chunk.device_id, compress_hyper_6_31_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk.device_id, compress_hyper_6_30_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_29_chunk.device_id, compress_hyper_6_29_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_28_chunk.device_id, compress_hyper_6_28_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(48 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_5_25_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=10 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_33_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) +(21 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Sort (actual rows=68370 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(22 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (never executed) + -> Seq Scan on compress_hyper_6_35_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (never executed) + -> Seq Scan on compress_hyper_6_34_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (never executed) + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (never executed) + -> Seq Scan on compress_hyper_6_32_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (never executed) + -> Seq Scan on compress_hyper_6_31_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (never executed) + -> Seq Scan on compress_hyper_6_30_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (never executed) + -> Seq Scan on compress_hyper_6_29_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (never executed) + -> Seq Scan on compress_hyper_6_28_chunk (never executed) +(21 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_22_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=12231 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 2769 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) +(35 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=12231 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 2769 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 +(35 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=41975 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 10794 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Merge Append (actual rows=16785 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=3357 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1681 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=10071 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 5043 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=3357 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1681 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(41 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=26390 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Merge Append (actual rows=8400 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1680 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3358 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=5040 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 10074 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1680 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3358 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 15114 + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(41 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=7195 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=0 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=0 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 10794 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=0 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Merge Append (actual rows=7195 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1439 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 2599 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=4317 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 7797 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1439 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 2599 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 +(40 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=3595 loops=1) + -> Merge Append (actual rows=3595 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=719 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4281 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=2157 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 12843 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=719 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4281 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=0 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=0 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 15114 + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=0 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) +(40 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_5_19_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_5_19_chunk."time")), _hyper_5_19_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_5_19_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_5_19_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_5_19_chunk."time")), _hyper_5_19_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=68370 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(35 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: metrics_space_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=68370 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(37 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Nested Loop (actual rows=136740 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Append (actual rows=68370 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=2) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=2) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=2) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=2) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=2) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=2) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=2) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=2) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=2) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=2) +(25 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(28 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: metrics_space_compressed."time" DESC + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk._ts_meta_sequence_num + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_6_33_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_6_36_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_6_36_chunk (never executed) + Filter: (device_id = 1) +(19 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(23 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=3600 loops=3) + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_1 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_2 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_3 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_4 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_6 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=3600 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_7 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_8 (actual rows=2160 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2438 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=5 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 7 + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_9 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 +(58 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Sort (actual rows=1 loops=2) + Sort Key: o."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=3600 loops=2) + -> Merge Append (actual rows=0 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_1 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_2 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_3 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=3600 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_4 (actual rows=720 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 780 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=2 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=2160 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2340 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=4 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 14 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_6 (actual rows=720 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 780 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=2 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=0 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_7 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_8 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_9 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 +(58 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=3600 loops=3) + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_1 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_2 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_3 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_4 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_6 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=3600 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_7 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_8 (actual rows=2160 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 2438 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=5 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 7 + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_9 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 +(58 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Sort (actual rows=0 loops=3) + Sort Key: o."time" DESC + Sort Method: quicksort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=0 loops=3) + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_1 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_2 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_3 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_4 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_6 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_7 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Rows Removed by Filter: 1533 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_8 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Rows Removed by Filter: 4598 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=5 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 7 + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_9 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Rows Removed by Filter: 1533 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 +(58 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Sort (actual rows=68370 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(25 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=68370 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Sort (actual rows=341846 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) +(82 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=2 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=26390 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=1680 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 358 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=3 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=5040 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1074 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=9 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 9 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=1680 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 358 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=3 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Materialize (actual rows=10 loops=1) + -> Sort (actual rows=6 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(61 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=5 loops=1) + InitPlan 1 (returns $0) + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk _hyper_5_19_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk _hyper_5_20_chunk_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk _hyper_5_21_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk _hyper_5_22_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk _hyper_5_23_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk _hyper_5_24_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk _hyper_5_25_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk _hyper_5_26_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk _hyper_5_27_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=5 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 999 + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=1 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 5 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=3 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 2997 + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=3 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 15 + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=1 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 999 + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=1 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 5 +(73 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=5 loops=1) + Hash Cond: (o1."time" = (max(_hyper_5_19_chunk."time"))) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Hash (actual rows=1 loops=1) + Buckets: 1024 Batches: 1 + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(46 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(25 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=0 loops=1) + Hash Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id) AND (o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (never executed) + -> Seq Scan on compress_hyper_6_35_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (never executed) + -> Seq Scan on compress_hyper_6_34_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (never executed) + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (never executed) + -> Seq Scan on compress_hyper_6_32_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (never executed) + -> Seq Scan on compress_hyper_6_31_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (never executed) + -> Seq Scan on compress_hyper_6_30_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (never executed) + -> Seq Scan on compress_hyper_6_29_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (never executed) + -> Seq Scan on compress_hyper_6_28_chunk (never executed) + -> Hash (actual rows=0 loops=1) + Buckets: 131072 Batches: 1 + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(46 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id)) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time", o1.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time", o2.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed o1 (actual rows=1 loops=1) + Order: o1."time" + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1_1 (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_2 (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_6_33_chunk._ts_meta_sequence_num DESC + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_3 (never executed) + -> Index Scan Backward using compress_hyper_6_30_chunk__compressed_hypertable_6_device_id__t on compress_hyper_6_30_chunk (never executed) + Index Cond: (device_id = 1) + -> Append (actual rows=100 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2 (actual rows=100 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2_1 (never executed) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_2 (never executed) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (never executed) + Filter: (device_id = 1) +(28 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + Join Filter: (o1."time" = o3."time") + Rows Removed by Join Filter: 1316920 + -> Merge Join (actual rows=20 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=4 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + -> Append (actual rows=65851 loops=20) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o3 (actual rows=3598 loops=20) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_2 (actual rows=4 loops=20) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o3_1 (actual rows=10794 loops=20) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_2 (actual rows=12 loops=20) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o3_2 (actual rows=3598 loops=20) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_2 (actual rows=4 loops=20) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o3_3 (actual rows=5038 loops=19) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_2 (actual rows=6 loops=19) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o3_4 (actual rows=15114 loops=19) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_2 (actual rows=18 loops=19) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o3_5 (actual rows=5038 loops=19) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_2 (actual rows=6 loops=19) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o3_6 (actual rows=5038 loops=19) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_2 (actual rows=6 loops=19) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o3_7 (actual rows=15114 loops=19) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_2 (actual rows=18 loops=19) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o3_8 (actual rows=5038 loops=19) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_2 (actual rows=6 loops=19) +(69 rows) + +-- get results for all the queries +-- run queries on uncompressed hypertable and store result +\set PREFIX '' +\set PREFIX_VERBOSE '' +\set ECHO none diff --git a/tsl/test/shared/expected/ordered_append-11.out b/tsl/test/shared/expected/ordered_append-11.out new file mode 100644 index 000000000..6b9c11b2c --- /dev/null +++ b/tsl/test/shared/expected/ordered_append-11.out @@ -0,0 +1,7903 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. +\set TEST_BASE_NAME ordered_append +SELECT + format('include/%s_query.sql', :'TEST_BASE_NAME') as "TEST_QUERY_NAME", + format('%s/shared/results/%s_results_uncompressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED", + format('%s/shared/results/%s_results_uncompressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED_IDX", + format('%s/shared/results/%s_results_compressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED", + format('%s/shared/results/%s_results_compressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED_IDX" +\gset +SELECT format('\! diff -u --label "Uncompressed results" --label "Compressed results" %s %s', :'TEST_RESULTS_UNCOMPRESSED', :'TEST_RESULTS_COMPRESSED') as "DIFF_CMD" +\gset +-- get EXPLAIN output for all variations +-- look at postgres version to decide whether we run with analyze or without +SELECT + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off)' + ELSE 'EXPLAIN (costs off)' + END AS "PREFIX", + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off, verbose)' + ELSE 'EXPLAIN (costs off, verbose)' + END AS "PREFIX_VERBOSE" +\gset +set work_mem to '64MB'; +set max_parallel_workers_per_gather to 0; +\set TEST_TABLE 'metrics' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) +(6 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_1_3_chunk."time" DESC, _hyper_1_3_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) +(8 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_1_3_chunk."time" DESC, _hyper_1_3_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) +(9 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + -> Index Only Scan using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(9 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk.device_id, _hyper_1_1_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) +(8 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk (actual rows=10 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 10 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 +(12 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Custom Scan (ChunkAppend) on metrics (actual rows=68370 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=17990 loops=1) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 +(8 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_2_chunk (never executed) + -> Seq Scan on _hyper_1_3_chunk (never executed) +(6 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(9 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(9 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(10 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(10 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 +(7 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + Chunks excluded during startup: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 +(7 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(14 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(14 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(15 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_1_1_chunk."time" DESC + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(15 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics."time") + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_1_1_chunk."time")), _hyper_1_1_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) +(9 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics."time") + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics."time") + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) +(6 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_1_1_chunk."time")), _hyper_1_1_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk (actual rows=25190 loops=1) +(9 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + Chunks excluded during startup: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 +(13 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=100 loops=1) + Order: metrics."time" DESC + Chunks excluded during startup: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=100 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 100 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 +(15 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Nested Loop (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=2 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) +(12 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=2 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(13 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 +(12 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=1 loops=3) + Order: o."time" DESC + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o_1 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o_2 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 +(16 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=1 loops=2) + Order: o."time" + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o_1 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o_2 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o_3 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 +(16 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=1 loops=3) + Order: o."time" DESC + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o_1 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o_2 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o_3 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 +(16 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +---------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Custom Scan (ChunkAppend) on metrics o (actual rows=0 loops=3) + Order: o."time" DESC + Chunks excluded during startup: 3 +(6 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Custom Scan (ChunkAppend) on metrics (actual rows=68370 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=17990 loops=1) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=25190 loops=1) + Heap Fetches: 25190 +(11 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=68370 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=17990 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 + -> Materialize (actual rows=341846 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=68370 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=17990 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 17990 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (actual rows=25190 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 25190 +(25 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=2 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=2 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 2 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Materialize (actual rows=10 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=6 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=6 loops=1) + Heap Fetches: 6 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on metrics (actual rows=5 loops=1) + Chunks excluded during runtime: 2 + InitPlan 2 (returns $1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics metrics_1 (actual rows=1 loops=1) + Order: metrics_1."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk _hyper_1_3_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk _hyper_1_2_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk _hyper_1_1_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=5 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 5 +(26 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Nested Loop (actual rows=5 loops=1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Append (actual rows=5 loops=1) + -> Index Only Scan using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_2 (actual rows=5 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 5 +(28 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=4 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(11 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(9 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=3 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_1_1_chunk."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(9 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=3 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=0 loops=1) + Hash Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id) AND (o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + -> Append (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_1_chunk o1 (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_2_chunk o1_1 (never executed) + -> Seq Scan on _hyper_1_3_chunk o1_2 (never executed) + -> Hash (actual rows=0 loops=1) + Buckets: 131072 Batches: 1 + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_1_1_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on _hyper_1_2_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on _hyper_1_3_chunk o2_2 (actual rows=25190 loops=1) +(16 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=20 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=21 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + Join Filter: (o1.device_id = o2.device_id) + Rows Removed by Join Filter: 400 + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=100 loops=1) + Order: o1."time" + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=100 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + -> Materialize (actual rows=500 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=101 loops=1) + Order: o2."time" + -> Index Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=101 loops=1) + -> Index Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + -> Index Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) +(16 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=1 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk o1_1 (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Append (actual rows=100 loops=1) + -> Index Only Scan using _hyper_1_1_chunk_metrics_device_id_time_idx on _hyper_1_1_chunk o2 (actual rows=100 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 100 + -> Index Only Scan using _hyper_1_2_chunk_metrics_device_id_time_idx on _hyper_1_2_chunk o2_1 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_1_3_chunk_metrics_device_id_time_idx on _hyper_1_3_chunk o2_2 (never executed) + Index Cond: (device_id = 1) + Heap Fetches: 0 +(24 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=20 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=20 loops=1) + Heap Fetches: 20 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=21 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=21 loops=1) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(20 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o3."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics o3 (actual rows=4 loops=1) + Order: o3."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o3_1 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o3_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o3_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Merge Join (actual rows=26 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=6 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o1_1 (actual rows=6 loops=1) + Heap Fetches: 6 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o1_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o1_3 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=26 loops=1) + -> Custom Scan (ChunkAppend) on metrics o2 (actual rows=6 loops=1) + Order: o2."time" + -> Index Only Scan Backward using _hyper_1_1_chunk_metrics_time_idx on _hyper_1_1_chunk o2_1 (actual rows=6 loops=1) + Heap Fetches: 6 + -> Index Only Scan Backward using _hyper_1_2_chunk_metrics_time_idx on _hyper_1_2_chunk o2_2 (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_1_3_chunk_metrics_time_idx on _hyper_1_3_chunk o2_3 (never executed) + Heap Fetches: 0 +(31 rows) + +\set TEST_TABLE 'metrics_space' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) +(18 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC, _hyper_2_12_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) +(14 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC, _hyper_2_12_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) +(15 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_device_id_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_device_id_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_device_id_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_device_id_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_device_id_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_device_id_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_device_id_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_device_id_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk.device_id, _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_device_id_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_device_id_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_device_id_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_device_id_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_device_id_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_device_id_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_device_id_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_device_id_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_2_10_chunk."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=10 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) +(9 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on metrics_space (actual rows=68370 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=10794 loops=1) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 +(26 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_5_chunk (never executed) + -> Seq Scan on _hyper_2_6_chunk (never executed) + -> Seq Scan on _hyper_2_7_chunk (never executed) + -> Seq Scan on _hyper_2_8_chunk (never executed) + -> Seq Scan on _hyper_2_9_chunk (never executed) + -> Seq Scan on _hyper_2_10_chunk (never executed) + -> Seq Scan on _hyper_2_11_chunk (never executed) + -> Seq Scan on _hyper_2_12_chunk (never executed) +(12 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(25 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 +(25 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=0 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=0 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=0 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=0 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(36 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 +(36 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=0 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=0 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=0 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=0 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: (("time" > ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 +(25 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: (("time" < ('2000-01-08'::cstring)::timestamp with time zone) AND ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 0 +(25 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------ + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(38 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(38 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(33 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------ + Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 +(33 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: time_bucket('@ 1 day'::interval, metrics_space."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_4_chunk."time")) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_7_chunk."time")) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_10_chunk."time")) + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) +(15 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_7_chunk."time")) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_10_chunk."time")) + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: date_trunc('day'::text, metrics_space."time") + -> Merge Append (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")) + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_7_chunk."time")) + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_2_10_chunk."time")) + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) +(18 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_2_4_chunk."time")), _hyper_2_4_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_4_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_6_chunk (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_9_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_10_chunk (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_12_chunk (actual rows=5038 loops=1) +(15 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 +(36 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=100 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=100 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=21 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=60 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 60 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=21 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 21 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 +(38 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Nested Loop (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=2 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) +(30 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=2 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=2 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(31 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Index Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Filter: (device_id = 1) +(9 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=1 loops=3) + Order: o."time" DESC + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_1 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_2 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_3 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_4."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_4 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_6 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=3) + Sort Key: o_7."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_7 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_8 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_9 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 3 +(38 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=1 loops=2) + Order: o."time" + -> Merge Append (actual rows=0 loops=2) + Sort Key: o_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_1 (actual rows=0 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_2 (actual rows=0 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_3 (actual rows=0 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=2) + Sort Key: o_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_4 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_6 (actual rows=1 loops=2) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_7 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_8 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_9 (never executed) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Heap Fetches: 0 +(38 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=1 loops=3) + Order: o."time" DESC + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_1 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_2 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_3 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_4."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_4 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_6 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 0 + -> Merge Append (actual rows=1 loops=3) + Sort Key: o_7."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_7 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_8 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_9 (actual rows=1 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Heap Fetches: 3 +(38 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Custom Scan (ChunkAppend) on metrics_space o (actual rows=0 loops=3) + Order: o."time" DESC + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o_1 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o_2 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o_3 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_4."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o_4 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o_5 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o_6 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=3) + Sort Key: o_7."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o_7 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o_8 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o_9 (actual rows=0 loops=3) + Index Cond: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Heap Fetches: 0 +(38 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=68370 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=10794 loops=1) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=3598 loops=1) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=15114 loops=1) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=5038 loops=1) + Heap Fetches: 5038 +(29 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=68370 loops=1) + Order: o1."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=10794 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Materialize (actual rows=341846 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=68370 loops=1) + Order: o2."time" + -> Merge Append (actual rows=17990 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=10794 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 10794 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 3598 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Merge Append (actual rows=25190 loops=1) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (actual rows=15114 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 15114 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 5038 +(73 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=2 loops=1) + Order: o1."time" + -> Merge Append (actual rows=2 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=2 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=1 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=1 loops=1) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Index Cond: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Heap Fetches: 0 + -> Materialize (actual rows=10 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=6 loops=1) + Order: o2."time" + -> Merge Append (actual rows=6 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(54 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on metrics_space (actual rows=5 loops=1) + InitPlan 2 (returns $1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space metrics_space_1 (actual rows=1 loops=1) + Order: metrics_space_1."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk _hyper_2_12_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk _hyper_2_11_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk _hyper_2_10_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk _hyper_2_9_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk _hyper_2_8_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk _hyper_2_7_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk _hyper_2_6_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk _hyper_2_5_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk _hyper_2_4_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=1) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Merge Append (actual rows=0 loops=1) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Merge Append (actual rows=5 loops=1) + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=3 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 1 +(70 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Nested Loop (actual rows=5 loops=1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=1 loops=1) + Order: metrics_space."time" DESC + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_2_12_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_9_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_6_chunk."time" DESC + -> Index Only Scan Backward using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Append (actual rows=5 loops=1) + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_1 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_2 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_3 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_4 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_5 (actual rows=0 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_6 (actual rows=1 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_7 (actual rows=3 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_8 (actual rows=1 loops=1) + Index Cond: ("time" = ($0)) + Heap Fetches: 1 +(70 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=4 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=4 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(29 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=3 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (actual rows=1 loops=1) + Heap Fetches: 1 +(21 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space (actual rows=3 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=3 loops=1) + Sort Key: _hyper_2_4_chunk."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_2_7_chunk."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_2_10_chunk."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=0 loops=1) + Hash Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id) AND (o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + -> Append (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_4_chunk o1 (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_5_chunk o1_1 (never executed) + -> Seq Scan on _hyper_2_6_chunk o1_2 (never executed) + -> Seq Scan on _hyper_2_7_chunk o1_3 (never executed) + -> Seq Scan on _hyper_2_8_chunk o1_4 (never executed) + -> Seq Scan on _hyper_2_9_chunk o1_5 (never executed) + -> Seq Scan on _hyper_2_10_chunk o1_6 (never executed) + -> Seq Scan on _hyper_2_11_chunk o1_7 (never executed) + -> Seq Scan on _hyper_2_12_chunk o1_8 (never executed) + -> Hash (actual rows=0 loops=1) + Buckets: 131072 Batches: 1 + -> Append (actual rows=68370 loops=1) + -> Seq Scan on _hyper_2_4_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_5_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on _hyper_2_6_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on _hyper_2_7_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_8_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_9_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_10_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on _hyper_2_11_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on _hyper_2_12_chunk o2_8 (actual rows=5038 loops=1) +(28 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=20 loops=1) + Order: o2."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=21 loops=1) + Order: o1."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + Join Filter: (o1.device_id = o2.device_id) + Rows Removed by Join Filter: 400 + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=100 loops=1) + Order: o1."time" + -> Merge Append (actual rows=100 loops=1) + Sort Key: o1_1."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=21 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=60 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=21 loops=1) + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + -> Materialize (actual rows=500 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=101 loops=1) + Order: o2."time" + -> Merge Append (actual rows=101 loops=1) + Sort Key: o2_1."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=21 loops=1) + -> Index Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=61 loops=1) + -> Index Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=21 loops=1) + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + -> Index Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + -> Index Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + -> Index Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + -> Index Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) +(40 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=1 loops=1) + Order: o1."time" + -> Index Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_2 (never executed) + Filter: (device_id = 1) + -> Index Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_3 (never executed) + Filter: (device_id = 1) + -> Materialize (actual rows=100 loops=1) + -> Append (actual rows=100 loops=1) + -> Seq Scan on _hyper_2_10_chunk o2 (actual rows=100 loops=1) + Filter: (device_id = 1) + -> Seq Scan on _hyper_2_4_chunk o2_1 (never executed) + Filter: (device_id = 1) + -> Seq Scan on _hyper_2_7_chunk o2_2 (never executed) + Filter: (device_id = 1) +(18 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=20 loops=1) + Order: o1."time" + -> Merge Append (actual rows=20 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=21 loops=1) + Order: o2."time" + -> Merge Append (actual rows=21 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=13 loops=1) + Heap Fetches: 13 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=5 loops=1) + Heap Fetches: 5 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(56 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o3."time" = o1."time") + -> Custom Scan (ChunkAppend) on metrics_space o3 (actual rows=4 loops=1) + Order: o3."time" + -> Merge Append (actual rows=4 loops=1) + Sort Key: o3_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o3_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o3_2 (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o3_3 (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: o3_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o3_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o3_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o3_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o3_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o3_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o3_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o3_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=100 loops=1) + -> Merge Join (actual rows=26 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=6 loops=1) + Order: o1."time" + -> Merge Append (actual rows=6 loops=1) + Sort Key: o1_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o1_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o1_2 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o1_3 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o1_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o1_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o1_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o1_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o1_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o1_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o1_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o1_9 (never executed) + Heap Fetches: 0 + -> Materialize (actual rows=26 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space o2 (actual rows=6 loops=1) + Order: o2."time" + -> Merge Append (actual rows=6 loops=1) + Sort Key: o2_1."time" + -> Index Only Scan using _hyper_2_4_chunk_metrics_space_time_idx on _hyper_2_4_chunk o2_1 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_2_5_chunk_metrics_space_time_idx on _hyper_2_5_chunk o2_2 (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan using _hyper_2_6_chunk_metrics_space_time_idx on _hyper_2_6_chunk o2_3 (actual rows=2 loops=1) + Heap Fetches: 2 + -> Merge Append (never executed) + Sort Key: o2_4."time" + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_time_idx on _hyper_2_7_chunk o2_4 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_8_chunk_metrics_space_time_idx on _hyper_2_8_chunk o2_5 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_9_chunk_metrics_space_time_idx on _hyper_2_9_chunk o2_6 (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: o2_7."time" + -> Index Only Scan using _hyper_2_10_chunk_metrics_space_time_idx on _hyper_2_10_chunk o2_7 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_11_chunk_metrics_space_time_idx on _hyper_2_11_chunk o2_8 (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_2_12_chunk_metrics_space_time_idx on _hyper_2_12_chunk o2_9 (never executed) + Heap Fetches: 0 +(85 rows) + +\set TEST_TABLE 'metrics_compressed' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(11 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC, _hyper_3_15_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(11 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC, _hyper_3_15_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(12 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(12 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_17_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_16_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(18 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk.device_id, _hyper_3_13_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk.device_id, compress_hyper_4_18_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_17_chunk.device_id, compress_hyper_4_17_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_16_chunk.device_id, compress_hyper_4_16_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(18 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_3_13_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=10 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk (actual rows=4 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_17_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk (actual rows=6 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Index Scan Backward using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) +(18 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Sort (actual rows=68370 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(10 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (never executed) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (never executed) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) +(9 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_14_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=20385 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 4615 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) +(15 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=20385 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 4615 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 +(15 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=41975 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=16785 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 8405 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(13 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=26390 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=8400 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 16790 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) +(13 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=7195 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=7195 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 12995 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 +(12 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=3595 loops=1) + Chunks excluded during startup: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=3595 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 21405 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=25 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 5 +(12 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(8 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_3_13_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_3_13_chunk."time")), _hyper_3_13_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_3_13_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_3_13_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_3_13_chunk."time")), _hyper_3_13_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=68370 loops=1) + Chunks excluded during startup: 0 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(15 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: metrics_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=68370 loops=1) + Chunks excluded during startup: 0 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(17 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Nested Loop (actual rows=136740 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Materialize (actual rows=2 loops=68370) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) +(14 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(16 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed (actual rows=1 loops=1) + Order: metrics_compressed."time" DESC + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=1 loops=1) + -> Index Scan using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_4_17_chunk._ts_meta_sequence_num + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_4_18_chunk._ts_meta_sequence_num + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk (never executed) + Index Cond: (device_id = 1) +(16 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_15_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) +(11 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=3600 loops=3) + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o_1 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o_2 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o_3 (actual rows=3600 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4063 + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=8 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 12 +(23 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Sort (actual rows=1 loops=2) + Sort Key: o."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=3600 loops=2) + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o_1 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_18_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o_2 (actual rows=3600 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 3900 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=8 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 22 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o_3 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) +(23 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=3600 loops=3) + Chunks excluded during startup: 0 + Chunks excluded during runtime: 2 + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o_1 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o_2 (never executed) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o_3 (actual rows=3600 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 4063 + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=8 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 12 +(23 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Sort (actual rows=0 loops=3) + Sort Key: o."time" DESC + Sort Method: quicksort + -> Custom Scan (ChunkAppend) on metrics_compressed o (actual rows=0 loops=3) + Chunks excluded during startup: 3 +(8 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Sort (actual rows=68370 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(13 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=68370 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Sort (actual rows=341846 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) +(34 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=2 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=26390 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=8400 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1790 + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 15 + -> Materialize (actual rows=10 loops=1) + -> Sort (actual rows=6 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(29 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Custom Scan (ChunkAppend) on metrics_compressed (actual rows=5 loops=1) + Chunks excluded during runtime: 1 + InitPlan 1 (returns $0) + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk _hyper_3_13_chunk_1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk _hyper_3_14_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk _hyper_3_15_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 20 + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (never executed) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=5 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 4995 + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=5 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 25 +(26 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=5 loops=1) + Hash Cond: (o1."time" = (max(_hyper_3_13_chunk."time"))) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Hash (actual rows=1 loops=1) + Buckets: 1024 Batches: 1 + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(22 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(13 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_3_13_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(11 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=0 loops=1) + Hash Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id) AND (o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (never executed) + -> Seq Scan on compress_hyper_4_17_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (never executed) + -> Seq Scan on compress_hyper_4_16_chunk (never executed) + -> Hash (actual rows=0 loops=1) + Buckets: 131072 Batches: 1 + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(22 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id)) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time", o1.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time", o2.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_compressed o1 (actual rows=1 loops=1) + Order: o1."time" + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1_1 (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_4_18_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk (actual rows=4 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_2 (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_4_17_chunk._ts_meta_sequence_num DESC + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_3 (never executed) + -> Index Scan Backward using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk (never executed) + Index Cond: (device_id = 1) + -> Materialize (actual rows=100 loops=1) + -> Append (actual rows=100 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=100 loops=1) + -> Index Scan using compress_hyper_4_18_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (never executed) + -> Index Scan using compress_hyper_4_17_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (never executed) + -> Index Scan using compress_hyper_4_16_chunk__compressed_hypertable_4_device_id__t on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (never executed) + Index Cond: (device_id = 1) +(29 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) +(23 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + Join Filter: (o1."time" = o3."time") + Rows Removed by Join Filter: 1316920 + -> Merge Join (actual rows=20 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=4 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o1_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o1_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk (actual rows=30 loops=1) + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o2 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_1 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o2_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o2_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_1 (actual rows=30 loops=1) + -> Materialize (actual rows=65851 loops=20) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_13_chunk o3 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_4_18_chunk compress_hyper_4_18_chunk_2 (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_14_chunk o3_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_17_chunk compress_hyper_4_17_chunk_2 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_3_15_chunk o3_2 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_4_16_chunk compress_hyper_4_16_chunk_2 (actual rows=30 loops=1) +(34 rows) + +\set TEST_TABLE 'metrics_space_compressed' +\ir :TEST_QUERY_NAME +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(23 rows) + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC, _hyper_5_27_chunk.device_id + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(23 rows) + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC, _hyper_5_27_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(24 rows) + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(24 rows) + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_35_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_34_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_33_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_32_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_31_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_29_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_28_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(48 rows) + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk.device_id, _hyper_5_19_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk.device_id, compress_hyper_6_36_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_35_chunk.device_id, compress_hyper_6_35_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_34_chunk.device_id, compress_hyper_6_34_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_33_chunk.device_id, compress_hyper_6_33_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_32_chunk.device_id, compress_hyper_6_32_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_31_chunk.device_id, compress_hyper_6_31_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk.device_id, compress_hyper_6_30_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_29_chunk.device_id, compress_hyper_6_29_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_28_chunk.device_id, compress_hyper_6_28_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(48 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Append (actual rows=10 loops=1) + Sort Key: _hyper_5_25_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=10 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_33_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) +(21 rows) + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Sort (actual rows=68370 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(22 rows) + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (never executed) + -> Seq Scan on compress_hyper_6_35_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (never executed) + -> Seq Scan on compress_hyper_6_34_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (never executed) + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (never executed) + -> Seq Scan on compress_hyper_6_32_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (never executed) + -> Seq Scan on compress_hyper_6_31_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (never executed) + -> Seq Scan on compress_hyper_6_30_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (never executed) + -> Seq Scan on compress_hyper_6_29_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (never executed) + -> Seq Scan on compress_hyper_6_28_chunk (never executed) +(21 rows) + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_22_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=12231 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 2769 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) +(35 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=12231 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 2769 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=4077 loops=1) + Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 +(35 rows) + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=41975 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 10794 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Merge Append (actual rows=16785 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=3357 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1681 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=10071 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 5043 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=3357 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1681 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(41 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=26390 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Merge Append (actual rows=8400 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1680 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3358 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=5040 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 10074 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1680 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3358 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 15114 + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(41 rows) + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=7195 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=0 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=0 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 10794 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=0 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 3598 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Merge Append (actual rows=7195 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=1439 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 2599 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=4317 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 7797 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=1439 loops=1) + Filter: (("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND ("time" > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 2599 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 +(40 rows) + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=3595 loops=1) + -> Merge Append (actual rows=3595 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=719 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4281 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=2157 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 12843 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=719 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4281 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=5 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1 + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=0 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=0 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 15114 + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=0 loops=1) + Filter: (("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND ("time" < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 5038 + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) +(40 rows) + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(20 rows) + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_5_19_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_5_19_chunk."time")), _hyper_5_19_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_5_19_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_5_19_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: (date_trunc('day'::text, _hyper_5_19_chunk."time")), _hyper_5_19_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: metrics_space_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=68370 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(35 rows) + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + CTE Scan on i (actual rows=100 loops=1) + CTE i + -> Limit (actual rows=100 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: metrics_space_compressed."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=68370 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(37 rows) + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Nested Loop (actual rows=136740 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Materialize (actual rows=2 loops=68370) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) +(26 rows) + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Nested Loop (actual rows=4 loops=1) + -> Values Scan on "*VALUES*" (actual rows=2 loops=1) + -> Materialize (actual rows=2 loops=2) + -> Subquery Scan on l (actual rows=2 loops=1) + -> Limit (actual rows=2 loops=1) + -> Sort (actual rows=2 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(28 rows) + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + QUERY PLAN +---------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=1 loops=1) + Order: metrics_space_compressed."time" DESC + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_30_chunk._ts_meta_sequence_num + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_6_33_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_6_36_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_6_36_chunk (never executed) + Filter: (device_id = 1) +(19 rows) + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_5_27_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) +(23 rows) + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=3600 loops=3) + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_1 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_2 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_3 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_4 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_6 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=3600 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_7 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_8 (actual rows=2160 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2438 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=5 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 7 + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_9 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 +(58 rows) + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=2 loops=1) + -> Function Scan on generate_series g (actual rows=2 loops=1) + -> Limit (actual rows=1 loops=2) + -> Sort (actual rows=1 loops=2) + Sort Key: o."time" + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=3600 loops=2) + -> Merge Append (actual rows=0 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_1 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_2 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_3 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=3600 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_4 (actual rows=720 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 780 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=2 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=2160 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2340 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=4 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 14 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_6 (actual rows=720 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 780 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=2 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=0 loops=2) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_7 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_8 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_9 (actual rows=0 loops=2) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval))) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=2) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 +(58 rows) + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=1 loops=3) + -> Sort (actual rows=1 loops=3) + Sort Key: o."time" DESC + Sort Method: top-N heapsort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=3600 loops=3) + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_1 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_2 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_3 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_4 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_6 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=3600 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_7 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_8 (actual rows=2160 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 2438 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=5 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 7 + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_9 (actual rows=720 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" < now())) + Rows Removed by Filter: 813 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 +(58 rows) + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join (actual rows=3 loops=1) + -> Function Scan on generate_series g (actual rows=3 loops=1) + -> Limit (actual rows=0 loops=3) + -> Sort (actual rows=0 loops=3) + Sort Key: o."time" DESC + Sort Method: quicksort + -> Custom Scan (ChunkAppend) on metrics_space_compressed o (actual rows=0 loops=3) + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o_1 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o_2 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o_3 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o_4 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o_5 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o_6 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=0 loops=3) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o_7 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Rows Removed by Filter: 1533 + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o_8 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Rows Removed by Filter: 4598 + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=5 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 7 + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o_9 (actual rows=0 loops=3) + Filter: (("time" >= g."time") AND ("time" < (g."time" + '@ 1 day'::interval)) AND ("time" > now())) + Rows Removed by Filter: 1533 + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=2 loops=3) + Filter: ((_ts_meta_max_1 >= g."time") AND (_ts_meta_min_1 < (g."time" + '@ 1 day'::interval))) + Rows Removed by Filter: 2 +(58 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + CTE Scan on cte (actual rows=68370 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + CTE cte + -> Sort (actual rows=68370 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(25 rows) + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Merge Join (actual rows=341850 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=68370 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Sort (actual rows=341846 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) +(82 rows) + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=10 loops=1) + -> Merge Join (actual rows=10 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=2 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=26390 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=1680 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 358 + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=3 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=5040 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 1074 + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=9 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 9 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=1680 loops=1) + Filter: ("time" < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 358 + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=3 loops=1) + Filter: (_ts_meta_min_1 < 'Sat Jan 08 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 3 + -> Materialize (actual rows=10 loops=1) + -> Sort (actual rows=6 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(61 rows) + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=5 loops=1) + InitPlan 1 (returns $0) + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk _hyper_5_19_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk _hyper_5_20_chunk_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk _hyper_5_21_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk _hyper_5_22_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk _hyper_5_23_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk _hyper_5_24_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk _hyper_5_25_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk _hyper_5_26_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk _hyper_5_27_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 6 + -> Merge Append (actual rows=5 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=1 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 999 + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=1 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 5 + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=3 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 2997 + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=3 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 15 + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=1 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 999 + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=1 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 5 +(73 rows) + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Sort (actual rows=5 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=5 loops=1) + Hash Cond: (o1."time" = (max(_hyper_5_19_chunk."time"))) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Hash (actual rows=1 loops=1) + Buckets: 1024 Batches: 1 + -> Aggregate (actual rows=1 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(46 rows) + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=4 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(25 rows) + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit (actual rows=3 loops=1) + -> Sort (actual rows=3 loops=1) + Sort Key: _hyper_5_19_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(23 rows) + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=0 loops=1) + -> Sort (actual rows=0 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Hash Join (actual rows=0 loops=1) + Hash Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id) AND (o1.v0 = o2.v0) AND (o1.v1 = o2.v1) AND (o1.v2 = o2.v2) AND (o1.v3 = o2.v3)) + -> Append (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (never executed) + -> Seq Scan on compress_hyper_6_35_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (never executed) + -> Seq Scan on compress_hyper_6_34_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (never executed) + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (never executed) + -> Seq Scan on compress_hyper_6_32_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (never executed) + -> Seq Scan on compress_hyper_6_31_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (never executed) + -> Seq Scan on compress_hyper_6_30_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (never executed) + -> Seq Scan on compress_hyper_6_29_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (never executed) + -> Seq Scan on compress_hyper_6_28_chunk (never executed) + -> Hash (actual rows=0 loops=1) + Buckets: 131072 Batches: 1 + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(46 rows) + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Left Join (actual rows=100 loops=1) + Merge Cond: (o2."time" = o1."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: ((o1."time" = o2."time") AND (o1.device_id = o2.device_id)) + -> Sort (actual rows=100 loops=1) + Sort Key: o1."time", o1.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time", o2.device_id + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + -> Custom Scan (ChunkAppend) on metrics_space_compressed o1 (actual rows=1 loops=1) + Order: o1."time" + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1_1 (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_6_36_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_2 (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_6_33_chunk._ts_meta_sequence_num DESC + -> Seq Scan on compress_hyper_6_33_chunk (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_3 (never executed) + -> Index Scan Backward using compress_hyper_6_30_chunk__compressed_hypertable_6_device_id__t on compress_hyper_6_30_chunk (never executed) + Index Cond: (device_id = 1) + -> Materialize (actual rows=100 loops=1) + -> Append (actual rows=100 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2 (actual rows=100 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2_1 (never executed) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_2 (never executed) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (never executed) + Filter: (device_id = 1) +(29 rows) + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Merge Join (actual rows=100 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=20 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=100 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) +(47 rows) + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=100 loops=1) + -> Nested Loop (actual rows=100 loops=1) + Join Filter: (o1."time" = o3."time") + Rows Removed by Join Filter: 1316920 + -> Merge Join (actual rows=20 loops=1) + Merge Cond: (o1."time" = o2."time") + -> Sort (actual rows=4 loops=1) + Sort Key: o1."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o1_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o1_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o1_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o1_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o1_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o1_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o1_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o1_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk (actual rows=6 loops=1) + -> Sort (actual rows=20 loops=1) + Sort Key: o2."time" + Sort Method: quicksort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o2_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_1 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o2_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_1 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o2_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o2_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o2_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o2_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_1 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o2_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_1 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o2_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_1 (actual rows=6 loops=1) + -> Materialize (actual rows=65851 loops=20) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_19_chunk o3 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_36_chunk compress_hyper_6_36_chunk_2 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_20_chunk o3_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_6_35_chunk compress_hyper_6_35_chunk_2 (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_21_chunk o3_2 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_6_34_chunk compress_hyper_6_34_chunk_2 (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_22_chunk o3_3 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_33_chunk compress_hyper_6_33_chunk_2 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_23_chunk o3_4 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_32_chunk compress_hyper_6_32_chunk_2 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_24_chunk o3_5 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_31_chunk compress_hyper_6_31_chunk_2 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_25_chunk o3_6 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_30_chunk compress_hyper_6_30_chunk_2 (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_26_chunk o3_7 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_6_29_chunk compress_hyper_6_29_chunk_2 (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_5_27_chunk o3_8 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_6_28_chunk compress_hyper_6_28_chunk_2 (actual rows=6 loops=1) +(70 rows) + +-- get results for all the queries +-- run queries on uncompressed hypertable and store result +\set PREFIX '' +\set PREFIX_VERBOSE '' +\set ECHO none diff --git a/tsl/test/shared/sql/.gitignore b/tsl/test/shared/sql/.gitignore new file mode 100644 index 000000000..497d20dca --- /dev/null +++ b/tsl/test/shared/sql/.gitignore @@ -0,0 +1,2 @@ +ordered_append-10.sql +ordered_append-11.sql diff --git a/tsl/test/shared/sql/CMakeLists.txt b/tsl/test/shared/sql/CMakeLists.txt new file mode 100644 index 000000000..1b31d9e20 --- /dev/null +++ b/tsl/test/shared/sql/CMakeLists.txt @@ -0,0 +1,33 @@ +set(TEST_FILES_SHARED +) + +set(TEST_TEMPLATES_SHARED +) + +if (${PG_VERSION_MAJOR} EQUAL "10" OR ${PG_VERSION_MAJOR} GREATER "10") + list(APPEND TEST_TEMPLATES_SHARED + ordered_append.sql.in + ) +endif() + +# Regression tests that vary with PostgreSQL version. Generated test +# files are put in the original source directory since all tests must +# be in the same directory. These files are updated when the template +# is edited, but not when the output file is deleted. If the output is +# deleted either recreate it manually, or rerun cmake on the root dir. +foreach(TEMPLATE_FILE ${TEST_TEMPLATES_SHARED}) + string(LENGTH ${TEMPLATE_FILE} TEMPLATE_NAME_LEN) + math(EXPR TEMPLATE_NAME_LEN ${TEMPLATE_NAME_LEN}-7) + string(SUBSTRING ${TEMPLATE_FILE} 0 ${TEMPLATE_NAME_LEN} TEMPLATE) + set(TEST_FILE ${TEMPLATE}-${TEST_VERSION_SUFFIX}.sql) + configure_file(${TEMPLATE_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/${TEST_FILE} COPYONLY) + list(APPEND TEST_FILES_SHARED ${TEST_FILE}) +endforeach(TEMPLATE_FILE) + +list(SORT TEST_FILES_SHARED) +file(REMOVE ${TEST_SCHEDULE_SHARED}) + +foreach(TEST_FILE ${TEST_FILES_SHARED}) + string(REGEX REPLACE "(.+)\.sql" "\\1" TESTS_TO_RUN ${TEST_FILE}) + file(APPEND ${TEST_SCHEDULE_SHARED} "test: ${TESTS_TO_RUN}\n") +endforeach(TEST_FILE) diff --git a/tsl/test/shared/sql/include/ordered_append_query.sql b/tsl/test/shared/sql/include/ordered_append_query.sql new file mode 100644 index 000000000..af364bc2d --- /dev/null +++ b/tsl/test/shared/sql/include/ordered_append_query.sql @@ -0,0 +1,314 @@ + +-- test ASC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + +-- test DESC for ordered chunks +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + +-- test query with ORDER BY column not in targetlist +:PREFIX SELECT + pg_typeof(device_id), pg_typeof(v2) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + +-- ORDER BY may include other columns after time column +:PREFIX SELECT + time, device_id, v0 +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + +-- test RECORD in targetlist +:PREFIX SELECT + (time, device_id, v0) +FROM :TEST_TABLE +ORDER BY time DESC, device_id LIMIT 1; + +-- test sort column not in targetlist +:PREFIX SELECT + time_bucket('1h',time) +FROM :TEST_TABLE +ORDER BY time DESC LIMIT 1; + +-- queries with ORDER BY non-time column shouldn't use ordered append +:PREFIX SELECT + device_id +FROM :TEST_TABLE +ORDER BY device_id LIMIT 1; + +-- time column must be primary sort order +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +ORDER BY device_id, time LIMIT 1; + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +:PREFIX SELECT + time, device_id +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY device_id, time LIMIT 10; + +-- queries without LIMIT should use ordered append +:PREFIX SELECT + time +FROM :TEST_TABLE +ORDER BY time ASC; + +-- queries without ORDER BY shouldnt use ordered append +:PREFIX SELECT + pg_typeof(time) +FROM :TEST_TABLE +LIMIT 1; + +-- test interaction with constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-07' +ORDER BY time DESC LIMIT 1; + +-- test interaction with runtime exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz +ORDER BY time ASC LIMIT 1; + +-- test constraint exclusion +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time > '2000-01-08'::text::timestamptz AND time < '2000-01-10' +ORDER BY time ASC LIMIT 1; + +:PREFIX SELECT + time +FROM :TEST_TABLE +WHERE time < '2000-01-08'::text::timestamptz AND time > '2000-01-07' +ORDER BY time ASC LIMIT 1; + +-- min/max queries +:PREFIX SELECT max(time) FROM :TEST_TABLE; + +:PREFIX SELECT min(time) FROM :TEST_TABLE; + +-- test first/last (doesn't use ordered append yet) +:PREFIX SELECT first(time, time) FROM :TEST_TABLE; + +:PREFIX SELECT last(time, time) FROM :TEST_TABLE; + +-- test query with time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY time ASC LIMIT 1; + +-- test query with ORDER BY time_bucket +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + +-- test query with ORDER BY time_bucket, device_id +-- must not use ordered append +:PREFIX SELECT + time_bucket('1d',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY time_bucket('1d',time), device_id LIMIT 1; + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + time_bucket('1d',time) +FROM :TEST_TABLE +ORDER BY date_trunc('day', time) LIMIT 1; + +-- test query with ORDER BY date_trunc +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1 LIMIT 1; + +-- test query with ORDER BY date_trunc, device_id +-- must not use ordered append +:PREFIX SELECT + date_trunc('day',time), device_id, v0 +FROM :TEST_TABLE +ORDER BY 1,2 LIMIT 1; + +-- test query with now() should result in ordered ChunkAppend +:PREFIX SELECT time FROM :TEST_TABLE WHERE time < now() + '1 month' +ORDER BY time DESC limit 1; + +-- test CTE +:PREFIX WITH i AS (SELECT time FROM :TEST_TABLE WHERE time < now() ORDER BY time DESC limit 100) +SELECT * FROM i; + +-- test LATERAL with ordered append in the outer query +:PREFIX SELECT time, pg_typeof(l) FROM :TEST_TABLE, LATERAL(SELECT * FROM (VALUES (1),(2)) v) l ORDER BY time DESC limit 2; + +-- test LATERAL with ordered append in the lateral query +:PREFIX SELECT time, pg_typeof(v) FROM (VALUES (1),(2)) v, LATERAL(SELECT * FROM :TEST_TABLE ORDER BY time DESC limit 2) l; + +-- test plan with best index is chosen +-- this should use device_id, time index +:PREFIX SELECT time, device_id FROM :TEST_TABLE WHERE device_id = 1 ORDER BY time DESC LIMIT 1; + +-- test plan with best index is chosen +-- this should use time index +:PREFIX SELECT time FROM :TEST_TABLE ORDER BY time DESC LIMIT 1; + +-- test LATERAL with correlated query +-- only last chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time DESC LIMIT 1 +) l ON true; + +-- test LATERAL with correlated query +-- only 2nd chunk should be executed +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-10'::timestamptz,'2000-01-11','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval ORDER BY time LIMIT 1 +) l ON true; + +-- test startup and runtime exclusion together +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time < now() ORDER BY time DESC LIMIT 1 +) l ON true; + +-- test startup and runtime exclusion together +-- all chunks should be filtered +:PREFIX SELECT g.time, l.time +FROM generate_series('2000-01-01'::timestamptz,'2000-01-03','1d') AS g(time) +LEFT OUTER JOIN LATERAL( + SELECT * FROM :TEST_TABLE o + WHERE o.time >= g.time AND o.time < g.time + '1d'::interval AND o.time > now() ORDER BY time DESC LIMIT 1 +) l ON true; + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS (SELECT time FROM :TEST_TABLE ORDER BY time) +SELECT * FROM cte WHERE time < '2000-02-01'::timestamptz; + +-- test JOIN +-- no exclusion on joined table because quals are not propagated yet +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time +WHERE o1.time < '2000-02-01' +ORDER BY o1.time; + +-- test JOIN +-- last chunk of o2 should not be executed +:PREFIX SELECT o1.time, o2.time +FROM :TEST_TABLE o1 +INNER JOIN (SELECT * FROM :TEST_TABLE o2 ORDER BY time) o2 ON o1.time = o2.time +WHERE o1.time < '2000-01-08' +ORDER BY o1.time LIMIT 10; + +-- test subquery +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT time +FROM :TEST_TABLE WHERE time = (SELECT max(time) FROM :TEST_TABLE) ORDER BY time; + +-- test join against max query +-- not ChunkAppend so no chunk exclusion +:PREFIX SELECT o1.time, o2.* +FROM :TEST_TABLE o1 INNER JOIN (SELECT max(time) AS max_time FROM :TEST_TABLE) o2 ON o1.time = o2.max_time ORDER BY time; + +-- test ordered append with limit expression +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT (SELECT length('four')); + +-- test with ordered guc disabled +SET timescaledb.enable_ordered_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + +RESET timescaledb.enable_ordered_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + +-- test with chunk append disabled +SET timescaledb.enable_chunk_append TO off; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + +RESET timescaledb.enable_chunk_append; +:PREFIX SELECT time +FROM :TEST_TABLE ORDER BY time LIMIT 3; + +-- test JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o1.time LIMIT 100; + +-- test JOIN on time column with USING +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 USING(time) ORDER BY o1.time LIMIT 100; + +-- test NATURAL JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 NATURAL INNER JOIN :TEST_TABLE o2 ORDER BY o1.time LIMIT 100; + +-- test LEFT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 LEFT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o1.time LIMIT 100; + +-- test RIGHT JOIN on time column +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 RIGHT JOIN :TEST_TABLE o2 ON o1.time=o2.time ORDER BY o2.time LIMIT 100; + +-- test JOIN on time column with ON clause expression order switched +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o2.time = o1.time ORDER BY o1.time LIMIT 100; + +-- test JOIN on time column with equality condition in WHERE clause +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON true WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + +-- test JOIN on time column with ORDER BY 2nd hypertable +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time ORDER BY o2.time LIMIT 100; + +-- test JOIN on time column and device_id +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id AND o1.time = o2.time ORDER BY o1.time LIMIT 100; + +-- test JOIN on device_id +-- should not use ordered append for 2nd hypertable +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.device_id = o2.device_id WHERE o1.device_id = 1 ORDER BY o1.time LIMIT 100; + +-- test JOIN on time column with implicit join +-- should use 2 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1, :TEST_TABLE o2 WHERE o1.time = o2.time ORDER BY o1.time LIMIT 100; + +-- test JOIN on time column with 3 hypertables +-- should use 3 ChunkAppend +:PREFIX SELECT o1.time FROM :TEST_TABLE o1 INNER JOIN :TEST_TABLE o2 ON o1.time = o2.time INNER JOIN :TEST_TABLE o3 ON o1.time = o3.time ORDER BY o1.time LIMIT 100; + diff --git a/tsl/test/shared/sql/include/shared_setup.sql b/tsl/test/shared/sql/include/shared_setup.sql new file mode 100644 index 000000000..44f2a12cb --- /dev/null +++ b/tsl/test/shared/sql/include/shared_setup.sql @@ -0,0 +1,70 @@ + +SET client_min_messages TO ERROR; + +-- create normal hypertable with dropped columns, each chunk will have different attribute numbers +CREATE TABLE metrics(filler_1 int, filler_2 int, filler_3 int, time timestamptz NOT NULL, device_id int, v0 int, v1 int, v2 float, v3 float); +CREATE INDEX ON metrics(time DESC); +CREATE INDEX ON metrics(device_id,time DESC); +SELECT create_hypertable('metrics','time',create_default_indexes:=false); + +ALTER TABLE metrics DROP COLUMN filler_1; +INSERT INTO metrics(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-05 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics DROP COLUMN filler_2; +INSERT INTO metrics(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id-1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-06 0:00:00+0'::timestamptz,'2000-01-12 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics DROP COLUMN filler_3; +INSERT INTO metrics(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-13 0:00:00+0'::timestamptz,'2000-01-19 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ANALYZE metrics; + +-- create identical hypertable with space partitioning +CREATE TABLE metrics_space(filler_1 int, filler_2 int, filler_3 int, time timestamptz NOT NULL, device_id int, v0 int, v1 float, v2 float, v3 float); +CREATE INDEX ON metrics_space(time); +CREATE INDEX ON metrics_space(device_id,time); +SELECT create_hypertable('metrics_space','time','device_id',3,create_default_indexes:=false); + +ALTER TABLE metrics_space DROP COLUMN filler_1; +INSERT INTO metrics_space(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-05 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics_space DROP COLUMN filler_2; +INSERT INTO metrics_space(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-06 0:00:00+0'::timestamptz,'2000-01-12 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics_space DROP COLUMN filler_3; +INSERT INTO metrics_space(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-13 0:00:00+0'::timestamptz,'2000-01-19 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ANALYZE metrics_space; + + +-- create hypertable with compression +CREATE TABLE metrics_compressed(filler_1 int, filler_2 int, filler_3 int, time timestamptz NOT NULL, device_id int, v0 int, v1 int, v2 float, v3 float); +CREATE INDEX ON metrics_compressed(time); +CREATE INDEX ON metrics_compressed(device_id,time); +SELECT create_hypertable('metrics_compressed','time',create_default_indexes:=false); + +ALTER TABLE metrics_compressed DROP COLUMN filler_1; +INSERT INTO metrics_compressed(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-05 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics_compressed DROP COLUMN filler_2; +INSERT INTO metrics_compressed(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id-1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-06 0:00:00+0'::timestamptz,'2000-01-12 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics_compressed DROP COLUMN filler_3; +INSERT INTO metrics_compressed(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-13 0:00:00+0'::timestamptz,'2000-01-19 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ANALYZE metrics_compressed; + +-- compress chunks +ALTER TABLE metrics_compressed SET (timescaledb.compress, timescaledb.compress_orderby='time DESC', timescaledb.compress_segmentby='device_id'); +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht where c.hypertable_id = ht.id and ht.table_name = 'metrics_compressed' and c.compressed_chunk_id IS NULL; + +-- create hypertable with space partitioning and compression +CREATE TABLE metrics_space_compressed(filler_1 int, filler_2 int, filler_3 int, time timestamptz NOT NULL, device_id int, v0 int, v1 float, v2 float, v3 float); +CREATE INDEX ON metrics_space_compressed(time); +CREATE INDEX ON metrics_space_compressed(device_id,time); +SELECT create_hypertable('metrics_space_compressed','time','device_id',3,create_default_indexes:=false); + +ALTER TABLE metrics_space_compressed DROP COLUMN filler_1; +INSERT INTO metrics_space_compressed(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-05 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics_space_compressed DROP COLUMN filler_2; +INSERT INTO metrics_space_compressed(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-06 0:00:00+0'::timestamptz,'2000-01-12 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ALTER TABLE metrics_space_compressed DROP COLUMN filler_3; +INSERT INTO metrics_space_compressed(time,device_id,v0,v1,v2,v3) SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL FROM generate_series('2000-01-13 0:00:00+0'::timestamptz,'2000-01-19 23:55:00+0','2m') gtime(time), generate_series(1,5,1) gdevice(device_id); +ANALYZE metrics_space_compressed; + +-- compress chunks +ALTER TABLE metrics_space_compressed SET (timescaledb.compress, timescaledb.compress_orderby='time DESC', timescaledb.compress_segmentby='device_id'); +SELECT compress_chunk(c.schema_name|| '.' || c.table_name) +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.hypertable ht where c.hypertable_id = ht.id and ht.table_name = 'metrics_space_compressed' and c.compressed_chunk_id IS NULL; + diff --git a/tsl/test/shared/sql/ordered_append-11.sql b/tsl/test/shared/sql/ordered_append-11.sql new file mode 100644 index 000000000..7401aa5c2 --- /dev/null +++ b/tsl/test/shared/sql/ordered_append-11.sql @@ -0,0 +1,72 @@ + +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. + +\set TEST_BASE_NAME ordered_append +SELECT + format('include/%s_query.sql', :'TEST_BASE_NAME') as "TEST_QUERY_NAME", + format('%s/shared/results/%s_results_uncompressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED", + format('%s/shared/results/%s_results_uncompressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED_IDX", + format('%s/shared/results/%s_results_compressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED", + format('%s/shared/results/%s_results_compressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED_IDX" +\gset +SELECT format('\! diff -u --label "Uncompressed results" --label "Compressed results" %s %s', :'TEST_RESULTS_UNCOMPRESSED', :'TEST_RESULTS_COMPRESSED') as "DIFF_CMD" +\gset + +-- get EXPLAIN output for all variations +-- look at postgres version to decide whether we run with analyze or without +SELECT + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off)' + ELSE 'EXPLAIN (costs off)' + END AS "PREFIX", + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off, verbose)' + ELSE 'EXPLAIN (costs off, verbose)' + END AS "PREFIX_VERBOSE" +\gset + +set work_mem to '64MB'; + +set max_parallel_workers_per_gather to 0; +\set TEST_TABLE 'metrics' +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_space' +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_compressed' +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_space_compressed' +\ir :TEST_QUERY_NAME + + +-- get results for all the queries +-- run queries on uncompressed hypertable and store result +\set PREFIX '' +\set PREFIX_VERBOSE '' +\set ECHO none +SET client_min_messages TO error; + +-- run queries on compressed hypertable and store result +\set TEST_TABLE 'metrics' +\o :TEST_RESULTS_UNCOMPRESSED +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_compressed' +\o :TEST_RESULTS_COMPRESSED +\ir :TEST_QUERY_NAME +\o + +-- diff compressed and uncompressed results +:DIFF_CMD + +-- do the same for space partitioned hypertable +\set TEST_TABLE 'metrics_space' +\o :TEST_RESULTS_UNCOMPRESSED +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_space_compressed' +\o :TEST_RESULTS_COMPRESSED +\ir :TEST_QUERY_NAME +\o + +-- diff compressed and uncompressed results +:DIFF_CMD diff --git a/tsl/test/shared/sql/ordered_append.sql.in b/tsl/test/shared/sql/ordered_append.sql.in new file mode 100644 index 000000000..7401aa5c2 --- /dev/null +++ b/tsl/test/shared/sql/ordered_append.sql.in @@ -0,0 +1,72 @@ + +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. + +\set TEST_BASE_NAME ordered_append +SELECT + format('include/%s_query.sql', :'TEST_BASE_NAME') as "TEST_QUERY_NAME", + format('%s/shared/results/%s_results_uncompressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED", + format('%s/shared/results/%s_results_uncompressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNCOMPRESSED_IDX", + format('%s/shared/results/%s_results_compressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED", + format('%s/shared/results/%s_results_compressed_idx.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED_IDX" +\gset +SELECT format('\! diff -u --label "Uncompressed results" --label "Compressed results" %s %s', :'TEST_RESULTS_UNCOMPRESSED', :'TEST_RESULTS_COMPRESSED') as "DIFF_CMD" +\gset + +-- get EXPLAIN output for all variations +-- look at postgres version to decide whether we run with analyze or without +SELECT + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off)' + ELSE 'EXPLAIN (costs off)' + END AS "PREFIX", + CASE WHEN current_setting('server_version_num')::int >= 100000 + THEN 'EXPLAIN (analyze, costs off, timing off, summary off, verbose)' + ELSE 'EXPLAIN (costs off, verbose)' + END AS "PREFIX_VERBOSE" +\gset + +set work_mem to '64MB'; + +set max_parallel_workers_per_gather to 0; +\set TEST_TABLE 'metrics' +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_space' +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_compressed' +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_space_compressed' +\ir :TEST_QUERY_NAME + + +-- get results for all the queries +-- run queries on uncompressed hypertable and store result +\set PREFIX '' +\set PREFIX_VERBOSE '' +\set ECHO none +SET client_min_messages TO error; + +-- run queries on compressed hypertable and store result +\set TEST_TABLE 'metrics' +\o :TEST_RESULTS_UNCOMPRESSED +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_compressed' +\o :TEST_RESULTS_COMPRESSED +\ir :TEST_QUERY_NAME +\o + +-- diff compressed and uncompressed results +:DIFF_CMD + +-- do the same for space partitioned hypertable +\set TEST_TABLE 'metrics_space' +\o :TEST_RESULTS_UNCOMPRESSED +\ir :TEST_QUERY_NAME +\set TEST_TABLE 'metrics_space_compressed' +\o :TEST_RESULTS_COMPRESSED +\ir :TEST_QUERY_NAME +\o + +-- diff compressed and uncompressed results +:DIFF_CMD diff --git a/tsl/test/sql/CMakeLists.txt b/tsl/test/sql/CMakeLists.txt index cf7177e48..ab8c1d342 100644 --- a/tsl/test/sql/CMakeLists.txt +++ b/tsl/test/sql/CMakeLists.txt @@ -1,37 +1,24 @@ set(TEST_FILES - continuous_aggs_dump.sql - continuous_aggs_errors.sql - continuous_aggs_usage.sql - continuous_aggs_watermark.sql - edition.sql - gapfill.sql - move.sql - partialize_finalize.sql - reorder.sql + continuous_aggs_dump.sql + continuous_aggs_errors.sql + continuous_aggs_usage.sql + continuous_aggs_watermark.sql + edition.sql + gapfill.sql + move.sql + partialize_finalize.sql + reorder.sql ) set(TEST_FILES_DEBUG - bgw_policy.sql - bgw_reorder_drop_chunks.sql - continuous_aggs.sql - continuous_aggs_bgw.sql - continuous_aggs_materialize.sql - continuous_aggs_multi.sql - ddl_hook.sql - tsl_tables.sql -) - -#only test for version PG10 onwards -set(TEST_FILES_DEBUG_GT_9 - compress_table.sql - compression.sql - compression_algos.sql - compression_ddl.sql - compression_errors.sql - compression_hypertable.sql - compression_segment_meta.sql - compression_bgw.sql - compress_bgw_drop_chunks.sql + bgw_policy.sql + bgw_reorder_drop_chunks.sql + continuous_aggs.sql + continuous_aggs_bgw.sql + continuous_aggs_materialize.sql + continuous_aggs_multi.sql + ddl_hook.sql + tsl_tables.sql ) set(TEST_TEMPLATES @@ -42,15 +29,26 @@ set(TEST_TEMPLATES ) #compression only for PG > 9 -set(TEST_TEMPLATES_DEBUG_GT_9 - compression_permissions.sql.in - transparent_decompression.sql.in -) - if (${PG_VERSION_MAJOR} GREATER "9") - list(APPEND TEST_FILES_DEBUG ${TEST_FILES_DEBUG_GT_9}) - list(APPEND TEST_TEMPLATES ${TEST_TEMPLATES_DEBUG_GT_9}) + + list(APPEND TEST_FILES_DEBUG + compress_table.sql + compression.sql + compression_algos.sql + compression_ddl.sql + compression_errors.sql + compression_hypertable.sql + compression_segment_meta.sql + compression_bgw.sql + compress_bgw_drop_chunks.sql + ) + + list(APPEND TEST_TEMPLATES_DEBUG + compression_permissions.sql.in + transparent_decompression.sql.in + ) endif () + if (CMAKE_BUILD_TYPE MATCHES Debug) list(APPEND TEST_FILES ${TEST_FILES_DEBUG}) endif(CMAKE_BUILD_TYPE MATCHES Debug) @@ -60,12 +58,6 @@ endif(CMAKE_BUILD_TYPE MATCHES Debug) # be in the same directory. These files are updated when the template # is edited, but not when the output file is deleted. If the output is # deleted either recreate it manually, or rerun cmake on the root dir. -if (${PG_VERSION_MAJOR} GREATER "9") - set(TEST_VERSION_SUFFIX ${PG_VERSION_MAJOR}) -else () - set(TEST_VERSION_SUFFIX ${PG_VERSION_MAJOR}.${PG_VERSION_MINOR}) -endif () - foreach(TEMPLATE_FILE ${TEST_TEMPLATES}) string(LENGTH ${TEMPLATE_FILE} TEMPLATE_NAME_LEN) math(EXPR TEMPLATE_NAME_LEN ${TEMPLATE_NAME_LEN}-7) @@ -82,3 +74,4 @@ foreach(TEST_FILE ${TEST_FILES}) string(REGEX REPLACE "(.+)\.sql" "\\1" TESTS_TO_RUN ${TEST_FILE}) file(APPEND ${TEST_SCHEDULE} "test: ${TESTS_TO_RUN}\n") endforeach(TEST_FILE) +