From 051ae51011f93d8f7eb88dba330545faf000305b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabr=C3=ADzio=20de=20Royes=20Mello?= Date: Sat, 7 Oct 2023 16:18:41 -0300 Subject: [PATCH] PG16: Reset PlannerInfo->placeholdersFrozen Reset the flag to control PlaceHolderInfo creation because we're copying the entire content of the (PlannerInfo *)root data structure when building the first/last path. https://github.com/postgres/postgres/commit/b3ff6c74 --- src/planner/agg_bookend.c | 8 +- .../shared/expected/ordered_append-16.out | 4474 +++++++++++++++++ 2 files changed, 4481 insertions(+), 1 deletion(-) create mode 100644 tsl/test/shared/expected/ordered_append-16.out diff --git a/src/planner/agg_bookend.c b/src/planner/agg_bookend.c index e08eb0986fd..88f178b37ae 100644 --- a/src/planner/agg_bookend.c +++ b/src/planner/agg_bookend.c @@ -60,9 +60,10 @@ #include #include +#include "compat/compat.h" +#include "extension.h" #include "planner.h" #include "utils.h" -#include "extension.h" typedef struct FirstLastAggInfo { @@ -585,6 +586,11 @@ build_first_last_path(PlannerInfo *root, FirstLastAggInfo *fl_info, Oid eqop, Oi subroot->parse = parse = copyObject(root->parse); IncrementVarSublevelsUp((Node *) parse, 1, 1); +#if PG16_GE + /* Reset placeholdersFrozen: https://github.com/postgres/postgres/commit/b3ff6c74 */ + subroot->placeholdersFrozen = false; +#endif + /* append_rel_list might contain outer Vars? */ subroot->append_rel_list = copyObject(root->append_rel_list); IncrementVarSublevelsUp((Node *) subroot->append_rel_list, 1, 1); diff --git a/tsl/test/shared/expected/ordered_append-16.out b/tsl/test/shared/expected/ordered_append-16.out new file mode 100644 index 00000000000..8b4b303f3e0 --- /dev/null +++ b/tsl/test/shared/expected/ordered_append-16.out @@ -0,0 +1,4474 @@ +-- 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. +SELECT + format('include/%s.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_compressed.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_COMPRESSED" +\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 +\set PREFIX 'EXPLAIN (analyze, costs off, timing off, summary off)' +\set PREFIX_VERBOSE 'EXPLAIN (analyze, costs off, timing off, summary off, verbose)' +set work_mem to '64MB'; +set max_parallel_workers_per_gather to 0; +\set TEST_TABLE 'metrics' +\ir :TEST_QUERY_NAME +-- 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. +-- In the following test cases, we test that certain indexes are used. By using the +-- timescaledb.enable_decompression_sorted_merge optimization, we are pushing a sort node +-- below the DecompressChunk node, which operates on the batches. This could lead to flaky +-- tests because the input data is small and PostgreSQL switches from IndexScans to +-- SequentialScans. Disable the optimization for the following tests to ensure we have +-- stable query plans in all CI environments. +SET timescaledb.enable_decompression_sorted_merge = 0; +-- 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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Index Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + -> Index Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) +(7 rows) + +-- ORDER BY may include other columns after time column +:PREFIX +SELECT time, + device_id, + v0 +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY time DESC, + device_id +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 Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) +(9 rows) + +-- test RECORD in targetlist +:PREFIX +SELECT (time, + device_id, + v0) +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY time DESC, + device_id +LIMIT 1; +QUERY PLAN + Limit (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) +(10 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) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(10 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_X_X_chunk.device_id + -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_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 +WHERE device_id IN (1, 2) +ORDER BY device_id, + time +LIMIT 1; +QUERY PLAN + Limit (actual rows=1 loops=1) + -> Incremental Sort (actual rows=1 loops=1) + Sort Key: _hyper_X_X_chunk.device_id, _hyper_X_X_chunk."time" + Presorted Key: _hyper_X_X_chunk.device_id + Full-sort Groups: 1 Sort Method: top-N heapsort + Pre-sorted Groups: 1 Sort Method: top-N heapsort + -> Merge Append (actual rows=13675 loops=1) + Sort Key: _hyper_X_X_chunk.device_id + -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=3599 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 3599 + -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=5039 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 5039 + -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=5039 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 5039 +(17 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +SET enable_seqscan TO false; +: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_X_X_chunk."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=10 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 10 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 1 +(12 rows) + +RESET enable_seqscan; +-- queries without LIMIT should use ordered append +:PREFIX +SELECT time +FROM :TEST_TABLE +WHERE device_id IN (1, 2) +ORDER BY time ASC; +QUERY PLAN + Custom Scan (ChunkAppend) on metrics (actual rows=27348 loops=1) + Order: metrics."time" + -> Index Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=7196 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 10794 + -> Index Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=10076 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 15114 + -> Index Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=10076 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 15114 +(11 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_X_X_chunk (actual rows=1 loops=1) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_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) + +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +-- 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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(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) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(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) + -> Result (actual rows=1 loops=1) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(10 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) + -> Result (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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(10 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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=7196 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=10076 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=10076 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) +(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) + -> Result (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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(10 rows) + +-- test query with ORDER BY date_trunc +:PREFIX +SELECT date_trunc('day', time) +FROM :TEST_TABLE +ORDER BY 1 +LIMIT 1; +QUERY PLAN + Limit (actual rows=1 loops=1) + -> Result (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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(10 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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=7196 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=10076 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=10076 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) +(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) + -> Custom Scan (ChunkAppend) on metrics (actual rows=1 loops=1) + Order: metrics."time" DESC + Chunks excluded during startup: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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 + 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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=100 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 100 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 +(13 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS ( + SELECT time + FROM :TEST_TABLE + WHERE device_id = 1 + ORDER BY time +) +SELECT * +FROM cte +WHERE time < '2000-02-01'::timestamptz; +QUERY PLAN + Custom Scan (ChunkAppend) on metrics (actual rows=13674 loops=1) + Order: metrics."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=3598 loops=1) + Index Cond: ((device_id = 1) AND ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 3598 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: ((device_id = 1) AND ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 5038 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: ((device_id = 1) AND ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone)) + Heap Fetches: 5038 +(11 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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=5 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 5 +(26 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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=4 loops=1) + Heap Fetches: 4 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_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_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(9 rows) + +\set TEST_TABLE 'metrics_space' +\ir :TEST_QUERY_NAME +-- 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. +-- In the following test cases, we test that certain indexes are used. By using the +-- timescaledb.enable_decompression_sorted_merge optimization, we are pushing a sort node +-- below the DecompressChunk node, which operates on the batches. This could lead to flaky +-- tests because the input data is small and PostgreSQL switches from IndexScans to +-- SequentialScans. Disable the optimization for the following tests to ensure we have +-- stable query plans in all CI environments. +SET timescaledb.enable_decompression_sorted_merge = 0; +-- 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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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) + -> Result (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_X_X_chunk."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) +(19 rows) + +-- ORDER BY may include other columns after time column +:PREFIX +SELECT time, + device_id, + v0 +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY time DESC, + device_id +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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Filter: (device_id = 1) +(9 rows) + +-- test RECORD in targetlist +:PREFIX +SELECT (time, + device_id, + v0) +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY time DESC, + device_id +LIMIT 1; +QUERY PLAN + Limit (actual rows=1 loops=1) + -> Result (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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Filter: (device_id = 1) + -> Index Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Filter: (device_id = 1) +(10 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) + -> Result (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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(28 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_X_X_chunk.device_id + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_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 +WHERE device_id IN (1, 2) +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_X_X_chunk.device_id, _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + Heap Fetches: 1 +(21 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +SET enable_seqscan TO false; +: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_X_X_chunk."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=10 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) +(9 rows) + +RESET enable_seqscan; +-- queries without LIMIT should use ordered append +:PREFIX +SELECT time +FROM :TEST_TABLE +WHERE device_id IN (1, 2) +ORDER BY time ASC; +QUERY PLAN + Custom Scan (ChunkAppend) on metrics_space (actual rows=27348 loops=1) + Order: metrics_space."time" + -> Merge Append (actual rows=7196 loops=1) + Sort Key: _hyper_X_X_chunk."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 7196 + -> Merge Append (actual rows=10076 loops=1) + Sort Key: _hyper_X_X_chunk."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 10076 + -> Merge Append (actual rows=10076 loops=1) + Sort Key: _hyper_X_X_chunk."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 10076 +(23 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_X_X_chunk (actual rows=1 loops=1) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_chunk (never executed) + -> Seq Scan on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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) + +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +-- 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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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) + -> 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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(39 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) + -> 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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 +(39 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) + -> Result (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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(28 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) + -> Result (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_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: (time_bucket('@ 1 day'::interval, _hyper_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(28 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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Seq Scan on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=3598 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) +(18 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) + -> Result (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_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(28 rows) + +-- test query with ORDER BY date_trunc +:PREFIX +SELECT date_trunc('day', time) +FROM :TEST_TABLE +ORDER BY 1 +LIMIT 1; +QUERY PLAN + Limit (actual rows=1 loops=1) + -> Result (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_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(28 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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Seq Scan on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=3598 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) + -> Seq Scan on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: (device_id = ANY ('{1,2}'::integer[])) +(18 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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < (now() + '@ 1 mon'::interval)) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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 + 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_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=21 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 21 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=60 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 60 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=21 loops=1) + Index Cond: ("time" < now()) + Heap Fetches: 21 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Index Cond: ("time" < now()) + Heap Fetches: 0 +(36 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS ( + SELECT time + FROM :TEST_TABLE + WHERE device_id = 1 + ORDER BY time +) +SELECT * +FROM cte +WHERE time < '2000-02-01'::timestamptz; +QUERY PLAN + Custom Scan (ChunkAppend) on metrics_space (actual rows=13674 loops=1) + Order: metrics_space."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=3598 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=5038 loops=1) + Index Cond: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + Filter: (device_id = 1) +(11 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_X_X_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=1 loops=1) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk_1."time" DESC + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_chunk_1 (never executed) + Index Cond: ("time" IS NOT NULL) + Heap Fetches: 0 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=0 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=3 loops=1) + Index Cond: ("time" = $1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: ("time" = $1) + 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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=3 loops=1) + Heap Fetches: 3 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_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_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=2 loops=1) + Heap Fetches: 2 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (actual rows=1 loops=1) + Heap Fetches: 1 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Merge Append (never executed) + Sort Key: _hyper_X_X_chunk."time" + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 + -> Index Only Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) + Heap Fetches: 0 +(27 rows) + +\set TEST_TABLE 'metrics_compressed' +\ir :TEST_QUERY_NAME +-- 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. +-- In the following test cases, we test that certain indexes are used. By using the +-- timescaledb.enable_decompression_sorted_merge optimization, we are pushing a sort node +-- below the DecompressChunk node, which operates on the batches. This could lead to flaky +-- tests because the input data is small and PostgreSQL switches from IndexScans to +-- SequentialScans. Disable the optimization for the following tests to ensure we have +-- stable query plans in all CI environments. +SET timescaledb.enable_decompression_sorted_merge = 0; +-- 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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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 +WHERE device_id = 1 +ORDER BY time DESC, + device_id +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_X_X_chunk (actual rows=1 loops=1) + -> Index Scan using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Index Scan using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Index Scan using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) +(12 rows) + +-- test RECORD in targetlist +:PREFIX +SELECT (time, + device_id, + v0) +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY time DESC, + device_id +LIMIT 1; +QUERY PLAN + Limit (actual rows=1 loops=1) + -> Result (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_X_X_chunk (actual rows=1 loops=1) + -> Index Scan using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Index Scan using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Index Scan using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (never executed) + Index Cond: (device_id = 1) +(13 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_X_X_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_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(18 rows) + +-- time column must be primary sort order +:PREFIX +SELECT time, + device_id +FROM :TEST_TABLE +WHERE device_id IN (1, 2) +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_X_X_chunk.device_id, _hyper_X_X_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(24 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +SET enable_seqscan TO false; +: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_X_X_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10 loops=1) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) +(12 rows) + +RESET enable_seqscan; +-- queries without LIMIT should use ordered append +:PREFIX +SELECT time +FROM :TEST_TABLE +WHERE device_id IN (1, 2) +ORDER BY time ASC; +QUERY PLAN + Sort (actual rows=27348 loops=1) + Sort Key: _hyper_X_X_chunk."time" + Sort Method: quicksort + -> Append (actual rows=27348 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(16 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_X_X_chunk (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=20385 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 4615 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=25190 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=20385 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 4615 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=16785 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3215 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 10 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) +(16 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_X_X_chunk (actual rows=17990 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=8400 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1790 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=15 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 15 +(16 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_X_X_chunk (actual rows=7195 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 7805 + Vectorized Filter: ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=15 loops=1) + Filter: ((_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 15 +(13 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_X_X_chunk (actual rows=3595 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 6405 + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=10 loops=1) + Filter: ((_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 20 +(13 rows) + +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +-- min/max queries +:PREFIX +SELECT max(time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) + +:PREFIX +SELECT min(time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX +SELECT first(time, time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) + +:PREFIX +SELECT last(time, time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(18 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_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(12 rows) + +-- test query with ORDER BY date_trunc +:PREFIX +SELECT date_trunc('day', 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: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=7196 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=8 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10076 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 18 +(18 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_X_X_chunk (actual rows=25190 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_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 + 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_X_X_chunk (actual rows=25190 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) +(15 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS ( + SELECT time + FROM :TEST_TABLE + WHERE device_id = 1 + ORDER BY time +) +SELECT * +FROM cte +WHERE time < '2000-02-01'::timestamptz; +QUERY PLAN + Custom Scan (ChunkAppend) on metrics_compressed (actual rows=13674 loops=1) + Order: metrics_compressed."time" + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + Vectorized Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Index Cond: (device_id = 1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Index Cond: (device_id = 1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_4_device_id__t on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Index Cond: (device_id = 1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) +(17 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: 2 + InitPlan 1 (returns $0) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 4995 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=5 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 25 +(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) + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) + +\set TEST_TABLE 'metrics_space_compressed' +\ir :TEST_QUERY_NAME +-- 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. +-- In the following test cases, we test that certain indexes are used. By using the +-- timescaledb.enable_decompression_sorted_merge optimization, we are pushing a sort node +-- below the DecompressChunk node, which operates on the batches. This could lead to flaky +-- tests because the input data is small and PostgreSQL switches from IndexScans to +-- SequentialScans. Disable the optimization for the following tests to ensure we have +-- stable query plans in all CI environments. +SET timescaledb.enable_decompression_sorted_merge = 0; +-- 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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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 +WHERE device_id = 1 +ORDER BY time DESC, + device_id +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_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk._ts_meta_sequence_num + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_X_X_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_X_X_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + Filter: (device_id = 1) +(19 rows) + +-- test RECORD in targetlist +:PREFIX +SELECT (time, + device_id, + v0) +FROM :TEST_TABLE +WHERE device_id = 1 +ORDER BY time DESC, + device_id +LIMIT 1; +QUERY PLAN + Limit (actual rows=1 loops=1) + -> Result (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_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk._ts_meta_sequence_num + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_X_X_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + Filter: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Sort (never executed) + Sort Key: compress_hyper_X_X_chunk._ts_meta_sequence_num + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + Filter: (device_id = 1) +(20 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_X_X_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_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(48 rows) + +-- time column must be primary sort order +:PREFIX +SELECT time, + device_id +FROM :TEST_TABLE +WHERE device_id IN (1, 2) +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_X_X_chunk.device_id, _hyper_X_X_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: compress_hyper_X_X_chunk.device_id, compress_hyper_X_X_chunk._ts_meta_sequence_num DESC + Sort Method: quicksort + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(42 rows) + +-- test equality constraint on ORDER BY prefix +-- currently not optimized +SET enable_seqscan TO false; +: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_X_X_chunk."time" + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10 loops=1) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_6_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_6_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1 loops=1) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_6_device_id__t on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Index Cond: (device_id = 1) +(12 rows) + +RESET enable_seqscan; +-- queries without LIMIT should use ordered append +:PREFIX +SELECT time +FROM :TEST_TABLE +WHERE device_id IN (1, 2) +ORDER BY time ASC; +QUERY PLAN + Sort (actual rows=27348 loops=1) + Sort Key: _hyper_X_X_chunk."time" + Sort Method: quicksort + -> Append (actual rows=27348 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(25 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_X_X_chunk (actual rows=1 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_chunk (never executed) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=4077 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=12231 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 2769 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=4077 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=15114 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" DESC + Sort Method: top-N heapsort + -> Append (actual rows=45575 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=15114 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=4077 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=12231 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 2769 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=4077 loops=1) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + Rows Removed by Filter: 923 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=16785 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3357 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 643 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 2 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10071 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1929 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3357 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 643 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 2 + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone) +(53 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_X_X_chunk (actual rows=3598 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + -> Merge Append (actual rows=8400 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1680 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 358 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=3 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5040 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1074 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=9 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 9 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1680 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 358 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=3 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3 + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 6 +(53 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_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Vectorized Filter: ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Vectorized Filter: ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Vectorized Filter: ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=7195 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1439 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1561 + Vectorized Filter: ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=3 loops=1) + Filter: ((_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 3 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=4317 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 4683 + Vectorized Filter: ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=9 loops=1) + Filter: ((_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 9 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=1439 loops=1) + Filter: ("time" > ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1561 + Vectorized Filter: ("time" < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=3 loops=1) + Filter: ((_ts_meta_min_1 < 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_max_1 > ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 3 +(46 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_X_X_chunk (actual rows=719 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1281 + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=2 loops=1) + Filter: ((_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=2157 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 3843 + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: ((_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=719 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Rows Removed by Filter: 1281 + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=2 loops=1) + Filter: ((_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 4 + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 6 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 18 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" < ('2000-01-08'::cstring)::timestamp with time zone) + Vectorized Filter: ("time" > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ((_ts_meta_max_1 > 'Fri Jan 07 00:00:00 2000 PST'::timestamp with time zone) AND (_ts_meta_min_1 < ('2000-01-08'::cstring)::timestamp with time zone)) + Rows Removed by Filter: 6 +(46 rows) + +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +-- min/max queries +:PREFIX +SELECT max(time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) + +:PREFIX +SELECT min(time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) + +-- test first/last (doesn't use ordered append yet) +:PREFIX +SELECT first(time, time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) + +:PREFIX +SELECT last(time, time) +FROM :TEST_TABLE; +QUERY PLAN + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(27 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_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(24 rows) + +-- test query with ORDER BY date_trunc +:PREFIX +SELECT date_trunc('day', 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: (date_trunc('day'::text, _hyper_X_X_chunk."time")) + Sort Method: top-N heapsort + -> Result (actual rows=68370 loops=1) + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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 +WHERE device_id IN (1, 2) +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_X_X_chunk."time")), _hyper_X_X_chunk.device_id + Sort Method: top-N heapsort + -> Result (actual rows=27348 loops=1) + -> Append (actual rows=27348 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 8 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Filter: (device_id = ANY ('{1,2}'::integer[])) + Rows Removed by Filter: 12 +(27 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_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: ("time" < (now() + '@ 1 mon'::interval)) + -> Seq Scan on compress_hyper_X_X_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 + 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_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=25190 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Merge Append (actual rows=17990 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + Filter: ("time" < now()) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) +(35 rows) + +-- test CTE +-- no chunk exclusion for CTE because cte query is not pulled up +:PREFIX WITH cte AS ( + SELECT time + FROM :TEST_TABLE + WHERE device_id = 1 + ORDER BY time +) +SELECT * +FROM cte +WHERE time < '2000-02-01'::timestamptz; +QUERY PLAN + Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=13674 loops=1) + Order: metrics_space_compressed."time" + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + Vectorized Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_6_device_id__t on compress_hyper_X_X_chunk (actual rows=4 loops=1) + Index Cond: (device_id = 1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_6_device_id__t on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Index Cond: (device_id = 1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + Vectorized Filter: ("time" < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) + -> Index Scan Backward using compress_hyper_X_X_chunk__compressed_hypertable_6_device_id__t on compress_hyper_X_X_chunk (actual rows=6 loops=1) + Index Cond: (device_id = 1) + Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) +(17 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) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Merge Append (actual rows=0 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=0 loops=1) + Filter: ("time" = $0) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=1 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 999 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=3 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 2997 + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk (actual rows=1 loops=1) + Filter: ("time" = $0) + Rows Removed by Filter: 999 + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=1 loops=1) + Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) + Rows Removed by Filter: 5 +(82 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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_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_X_X_chunk."time" + Sort Method: top-N heapsort + -> Append (actual rows=68370 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(23 rows) + +-- get results for all the queries +-- run queries on uncompressed hypertable and store result +\set PREFIX '' +\set PREFIX_VERBOSE '' +\set ECHO none