@@ -1365,6 +1365,7 @@ SELECT "time","hin"::text,"model"::text,"block"::text,"message_name"::text,"sign
13651365--------------------------+---------+----------+---------+--------------+-------------+----------------------+---------------------
13661366 Wed Jan 01 10:00:00 2020 | hin1111 | model111 | blok111 | message_here | signal1 | 12.34 | 12.34
13671367
1368+ drop table bugtab cascade;
13681369-- Condition that filter the first tuple of a batch - Issue 5797
13691370CREATE TABLE test (
13701371 id bigint,
@@ -1528,4 +1529,87 @@ SELECT t.dttm FROM test t ORDER BY t.dttm LIMIT 1;
15281529 Output: compress_hyper_14_26_chunk._ts_meta_count, compress_hyper_14_26_chunk.otherid, compress_hyper_14_26_chunk.valuefk, compress_hyper_14_26_chunk.otherfk, compress_hyper_14_26_chunk.id, compress_hyper_14_26_chunk._ts_meta_min_1, compress_hyper_14_26_chunk._ts_meta_max_1, compress_hyper_14_26_chunk.dttm, compress_hyper_14_26_chunk.measure
15291530
15301531RESET enable_sort;
1532+ drop table test cascade;
1533+ -- Test issue #9922: wrong sort order for Batch Sorted Merge with multikey minmax index
1534+ \c :TEST_DBNAME :ROLE_SUPERUSER
1535+ CREATE TABLE bsm_segby(ts timestamptz NOT NULL, grp int NOT NULL, name text NOT NULL);
1536+ SELECT table_name FROM create_hypertable('bsm_segby','ts',chunk_time_interval=>interval '100 day');
1537+ table_name
1538+ ------------
1539+ bsm_segby
1540+
1541+ ALTER TABLE bsm_segby SET (timescaledb.compress, timescaledb.compress_segmentby='grp', timescaledb.compress_orderby='name asc, ts asc');
1542+ INSERT INTO bsm_segby
1543+ SELECT '2024-08-01'::timestamptz + g*interval '1 min', g%4, 'k'||lpad(((g*5)%17)::text,3,'0')
1544+ FROM generate_series(0,4379) g;
1545+ SELECT count(compress_chunk(c)) FROM show_chunks('bsm_segby') c;
1546+ count
1547+ -------
1548+ 1
1549+
1550+ select schema_name || '.' || table_name chunk from _timescaledb_catalog.chunk
1551+ where id = (select compressed_chunk_id from _timescaledb_catalog.chunk
1552+ where hypertable_id = (select id from _timescaledb_catalog.hypertable
1553+ where table_name = 'bsm_segby') limit 1)
1554+ \gset
1555+ -- Firstlast index is used with Batch Sorted Merge: correct result
1556+ set timescaledb.debug_require_batch_sorted_merge = 'force';
1557+ SELECT count(*) misorder FROM (
1558+ SELECT name, ts, lag(name) OVER () pn, lag(ts) OVER () pt
1559+ FROM (SELECT name, ts FROM bsm_segby ORDER BY name, ts) s) z
1560+ WHERE pn IS NOT NULL AND (name<pn OR (name=pn AND ts<pt));
1561+ misorder
1562+ ----------
1563+ 0
1564+
1565+ -- Remove firstlast index from leading column: still OK to use Batch Sorted Merge
1566+ update _timescaledb_catalog.compression_settings
1567+ set index = '[{"type": "minmax", "column": "name", "source": "orderby"}, {"type": "minmax", "column": "ts", "source": "orderby"}, {"type": "firstlast", "column": "ts", "source": "orderby"}]'
1568+ where relid = 'bsm_segby'::regclass;
1569+ update _timescaledb_catalog.compression_settings
1570+ set index = '[{"type": "minmax", "column": "name", "source": "orderby"}, {"type": "minmax", "column": "ts", "source": "orderby"}, {"type": "firstlast", "column": "ts", "source": "orderby"}]'
1571+ where compress_relid = (select format('%I.%I', schema_name, table_name)::regclass AS chunk_regclass from _timescaledb_catalog.chunk
1572+ where id = (select compressed_chunk_id from _timescaledb_catalog.chunk
1573+ where hypertable_id = (select id from _timescaledb_catalog.hypertable
1574+ where table_name = 'bsm_segby') limit 1));
1575+ create index compressed_index_minmax_firstlast on :chunk (grp, _ts_meta_min_1, _ts_meta_max_1, _ts_meta_v2_first_ts, _ts_meta_v2_last_ts);
1576+ -- Correct result with Batch Sorted Merge
1577+ set timescaledb.debug_require_batch_sorted_merge = 'force';
1578+ SELECT count(*) misorder FROM (
1579+ SELECT name, ts, lag(name) OVER () pn, lag(ts) OVER () pt
1580+ FROM (SELECT name, ts FROM bsm_segby ORDER BY name, ts) s) z
1581+ WHERE pn IS NOT NULL AND (name<pn OR (name=pn AND ts<pt));
1582+ misorder
1583+ ----------
1584+ 0
1585+
1586+ -- Now use minmax index on non-leading column "ts"
1587+ drop index _timescaledb_internal.compressed_index_minmax_firstlast;
1588+ create index compressed_index_minmax_minmax on :chunk (grp, _ts_meta_min_1, _ts_meta_max_1, _ts_meta_min_2, _ts_meta_max_2);
1589+ -- Remove firstlast index from all columns
1590+ update _timescaledb_catalog.compression_settings
1591+ set index = '[{"type": "minmax", "column": "name", "source": "orderby"}, {"type": "minmax", "column": "ts", "source": "orderby"}]'
1592+ where relid = 'bsm_segby'::regclass;
1593+ update _timescaledb_catalog.compression_settings
1594+ set index = '[{"type": "minmax", "column": "name", "source": "orderby"}, {"type": "minmax", "column": "ts", "source": "orderby"}]'
1595+ where compress_relid = (select format('%I.%I', schema_name, table_name)::regclass AS chunk_regclass from _timescaledb_catalog.chunk
1596+ where id = (select compressed_chunk_id from _timescaledb_catalog.chunk
1597+ where hypertable_id = (select id from _timescaledb_catalog.hypertable
1598+ where table_name = 'bsm_segby') limit 1));
1599+ -- Correct result only when cannot use Batch Sorted Merge
1600+ set timescaledb.debug_require_batch_sorted_merge = 'forbid';
1601+ SELECT count(*) misorder FROM (
1602+ SELECT name, ts, lag(name) OVER () pn, lag(ts) OVER () pt
1603+ FROM (SELECT name, ts FROM bsm_segby ORDER BY name, ts) s) z
1604+ WHERE pn IS NOT NULL AND (name<pn OR (name=pn AND ts<pt));
1605+ misorder
1606+ ----------
1607+ 0
1608+
1609+ drop table bsm_segby cascade;
1610+ drop table test1 cascade;
1611+ drop table test2 cascade;
1612+ drop table test_with_defined_null cascade;
1613+ drop table test_costs cascade;
1614+ drop table insert_test cascade;
15311615reset timescaledb.debug_require_batch_sorted_merge;
0 commit comments