@@ -435,6 +435,40 @@ SELECT DISTINCT status FROM _timescaledb_catalog.chunk WHERE compressed_chunk_id
435435--------
436436 3
437437
438+ ROLLBACK;
439+ -- cagg + direct compress where the cagg time column is segmentby.
440+ -- segmentby columns don't get _ts_meta_min/max columns, so no MINMAX builder
441+ -- is created for them; the flush path must still derive an invalidation range
442+ -- from the segmentby value rather than crashing.
443+ BEGIN;
444+ CREATE TABLE metrics_segmentby_time (time TIMESTAMPTZ NOT NULL, device TEXT, value float)
445+ WITH (tsdb.hypertable);
446+ NOTICE: using column "time" as partitioning column
447+ CREATE MATERIALIZED VIEW metrics_segmentby_time_cagg WITH (tsdb.continuous) AS
448+ SELECT time_bucket('1 hour', time) AS bucket, device, avg(value) AS avg_value
449+ FROM metrics_segmentby_time GROUP BY bucket, device WITH NO DATA;
450+ ALTER TABLE metrics_segmentby_time SET (
451+ timescaledb.compress,
452+ timescaledb.compress_segmentby = 'time'
453+ );
454+ NOTICE: updated compression settings will only apply to future compressions
455+ INSERT INTO metrics_segmentby_time
456+ SELECT '2025-01-01'::timestamptz + (i * interval '5 minutes'), 'd1', random()
457+ FROM generate_series(1, 50) i;
458+ SET timescaledb.enable_direct_compress_insert = true;
459+ INSERT INTO metrics_segmentby_time
460+ SELECT '2025-02-01'::timestamptz + (i * interval '1 second'), 'd1', random()
461+ FROM generate_series(1, 5000) i;
462+ -- The new chunk should be in COMPRESSED state, confirming the flush path ran.
463+ SELECT _timescaledb_functions.chunk_status_text(chunk)
464+ FROM show_chunks('metrics_segmentby_time') chunk
465+ WHERE chunk::text LIKE '%hyper_%'
466+ ORDER BY chunk::text;
467+ chunk_status_text
468+ ------------------------
469+ {}
470+ {COMPRESSED,UNORDERED}
471+
438472ROLLBACK;
439473-- test chunk status handling
440474CREATE TABLE metrics_status(time timestamptz) WITH (tsdb.hypertable,tsdb.partition_column='time');
@@ -514,7 +548,7 @@ SELECT _timescaledb_functions.chunk_status_text(chunk) FROM show_chunks('metrics
514548SELECT compress_chunk(show_chunks('metrics_status'));
515549 compress_chunk
516550-----------------------------------------
517- _timescaledb_internal._hyper_4_54_chunk
551+ _timescaledb_internal._hyper_7_57_chunk
518552
519553-- status should be COMPRESSED
520554SELECT _timescaledb_functions.chunk_status_text(chunk) FROM show_chunks('metrics_status') chunk;
@@ -563,7 +597,7 @@ EXPLAIN (costs off,summary off,timing off) INSERT INTO :CHUNK SELECT '2025-01-01
563597--- QUERY PLAN ---
564598 Custom Scan (ModifyHypertable)
565599 Direct Compress: true
566- -> Insert on _hyper_6_56_chunk
600+ -> Insert on _hyper_9_59_chunk
567601 -> Function Scan on generate_series i
568602
569603BEGIN;
@@ -586,8 +620,8 @@ EXPLAIN (analyze,buffers off,costs off,summary off,timing off) DELETE FROM :CHUN
586620 Batches scanned: 1
587621 Batches decompressed: 1
588622 Tuples decompressed: 101
589- -> Delete on _hyper_6_56_chunk (actual rows=0.00 loops=1)
590- -> Index Scan using _hyper_6_56_chunk_metrics_chunk_time_idx on _hyper_6_56_chunk (actual rows=100.00 loops=1)
623+ -> Delete on _hyper_9_59_chunk (actual rows=0.00 loops=1)
624+ -> Index Scan using _hyper_9_59_chunk_metrics_chunk_time_idx on _hyper_9_59_chunk (actual rows=100.00 loops=1)
591625 Index Cond: ("time" > 'Wed Jan 01 00:00:00 2025 PST'::timestamp with time zone)
592626
593627SELECT count(*) FROM :CHUNK;
@@ -615,8 +649,8 @@ SET timescaledb.direct_compress_insert_tuple_sort_limit = 1000;
615649INSERT INTO metrics SELECT '2025-01-02'::timestamptz + (i || ' minute')::interval, 'd1', i::float FROM generate_series(1,3000) i;
616650EXPLAIN (ANALYZE, BUFFERS OFF, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM metrics;
617651--- QUERY PLAN ---
618- Custom Scan (ColumnarScan) on _hyper_1_59_chunk (actual rows=3000.00 loops=1)
619- -> Seq Scan on compress_hyper_2_60_chunk (actual rows=3.00 loops=1)
652+ Custom Scan (ColumnarScan) on _hyper_1_62_chunk (actual rows=3000.00 loops=1)
653+ -> Seq Scan on compress_hyper_2_63_chunk (actual rows=3.00 loops=1)
620654
621655SELECT first(time,rn), last(time,rn) FROM (SELECT ROW_NUMBER() OVER () as rn, time FROM metrics) sub;
622656 first | last
@@ -694,18 +728,18 @@ ANALYZE test_segmentby_stats;
694728SELECT compress_chunk(c) FROM show_chunks('test_segmentby_stats') c;
695729 compress_chunk
696730------------------------------------------
697- _timescaledb_internal._hyper_12_89_chunk
731+ _timescaledb_internal._hyper_15_92_chunk
698732
699733-- will have devide_id as default segmentby for compressed chunk;
700734SELECT * FROM _timescaledb_catalog.compression_settings;
701735 relid | compress_relid | segmentby | orderby | orderby_desc | orderby_nullsfirst | index
702736------------------------------------------+--------------------------------------------------+-------------+---------+--------------+--------------------+-------------------------------------------------------------
703737 metrics | | | {time} | {f} | {f} | [{"type": "minmax", "column": "time", "source": "orderby"}]
704738 metrics_status | | | | | |
705- _timescaledb_internal._hyper_4_54_chunk | _timescaledb_internal.compress_hyper_5_55_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
739+ _timescaledb_internal._hyper_7_57_chunk | _timescaledb_internal.compress_hyper_8_58_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
706740 metrics_chunk | | | | | |
707741 test_segmentby_stats | | | | | |
708- _timescaledb_internal._hyper_12_89_chunk | _timescaledb_internal.compress_hyper_13_90_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
742+ _timescaledb_internal._hyper_15_92_chunk | _timescaledb_internal.compress_hyper_16_93_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
709743
710744SET timescaledb.enable_direct_compress_insert = true;
711745INSERT INTO test_segmentby_stats
@@ -719,11 +753,11 @@ SELECT * FROM _timescaledb_catalog.compression_settings;
719753------------------------------------------+--------------------------------------------------+-------------+---------+--------------+--------------------+-------------------------------------------------------------
720754 metrics | | | {time} | {f} | {f} | [{"type": "minmax", "column": "time", "source": "orderby"}]
721755 metrics_status | | | | | |
722- _timescaledb_internal._hyper_4_54_chunk | _timescaledb_internal.compress_hyper_5_55_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
756+ _timescaledb_internal._hyper_7_57_chunk | _timescaledb_internal.compress_hyper_8_58_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
723757 metrics_chunk | | | | | |
724758 test_segmentby_stats | | | | | |
725- _timescaledb_internal._hyper_12_89_chunk | _timescaledb_internal.compress_hyper_13_90_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
726- _timescaledb_internal._hyper_12_91_chunk | _timescaledb_internal.compress_hyper_13_93_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
759+ _timescaledb_internal._hyper_15_92_chunk | _timescaledb_internal.compress_hyper_16_93_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
760+ _timescaledb_internal._hyper_15_94_chunk | _timescaledb_internal.compress_hyper_16_96_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
727761
728762ROLLBACK;
729763BEGIN;
@@ -746,10 +780,10 @@ SELECT * FROM _timescaledb_catalog.compression_settings;
746780------------------------------------------+--------------------------------------------------+-------------+---------+--------------+--------------------+-------------------------------------------------------------
747781 metrics | | | {time} | {f} | {f} | [{"type": "minmax", "column": "time", "source": "orderby"}]
748782 metrics_status | | | | | |
749- _timescaledb_internal._hyper_4_54_chunk | _timescaledb_internal.compress_hyper_5_55_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
783+ _timescaledb_internal._hyper_7_57_chunk | _timescaledb_internal.compress_hyper_8_58_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
750784 metrics_chunk | | | | | |
751785 test_segmentby_stats | | {device_id} | | | |
752- _timescaledb_internal._hyper_14_94_chunk | _timescaledb_internal.compress_hyper_15_95_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
786+ _timescaledb_internal._hyper_17_97_chunk | _timescaledb_internal.compress_hyper_18_98_chunk | {device_id} | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
753787
754788ROLLBACK;
755789-- Test orderby columns are not selected by DC segmentby default
@@ -767,13 +801,13 @@ SET timescaledb.enable_direct_compress_insert = on;
767801INSERT INTO test_orderby_not_segmentby SELECT '2024-06-01'::timestamptz + (i||' min')::interval,
768802 (i%5)+1, random() FROM generate_series(1,2000) i;
769803SELECT * FROM _timescaledb_catalog.compression_settings;
770- relid | compress_relid | segmentby | orderby | orderby_desc | orderby_nullsfirst | index
771- ------------------------------------------+ --------------------------------------------------+-----------+------------------+--------------+--------------------+-----------------------------------------------------------------------------------------------------------------------------
772- metrics | | | {time} | {f} | {f} | [{"type": "minmax", "column": "time", "source": "orderby"}]
773- metrics_status | | | | | |
774- _timescaledb_internal._hyper_4_54_chunk | _timescaledb_internal.compress_hyper_5_55_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
775- metrics_chunk | | | | | |
776- test_orderby_not_segmentby | | | | | |
777- _timescaledb_internal._hyper_16_97_chunk | _timescaledb_internal.compress_hyper_17_98_chunk | | {time,device_id} | {t,f} | {t,f} | [{"type": "minmax", "column": "time", "source": "orderby"}, {"type": "minmax", "column": "device_id", "source": "orderby"}]
804+ relid | compress_relid | segmentby | orderby | orderby_desc | orderby_nullsfirst | index
805+ -------------------------------------------+- --------------------------------------------------+-----------+------------------+--------------+--------------------+-----------------------------------------------------------------------------------------------------------------------------
806+ metrics | | | {time} | {f} | {f} | [{"type": "minmax", "column": "time", "source": "orderby"}]
807+ metrics_status | | | | | |
808+ _timescaledb_internal._hyper_7_57_chunk | _timescaledb_internal.compress_hyper_8_58_chunk | | {time} | {t} | {t} | [{"type": "minmax", "column": "time", "source": "orderby"}]
809+ metrics_chunk | | | | | |
810+ test_orderby_not_segmentby | | | | | |
811+ _timescaledb_internal._hyper_19_100_chunk | _timescaledb_internal.compress_hyper_20_101_chunk | | {time,device_id} | {t,f} | {t,f} | [{"type": "minmax", "column": "time", "source": "orderby"}, {"type": "minmax", "column": "device_id", "source": "orderby"}]
778812
779813ROLLBACK;
0 commit comments