@@ -1056,3 +1056,102 @@ FROM concurrent_compressed_merge,
10561056 2 | 1
10571057
10581058DROP TABLE concurrent_compressed_merge;
1059+ -- Test merging compressed chunks whose sparse indexes are logically the same
1060+ -- but the JSONB entries mismatch
1061+ CREATE TABLE merge_sparse_order(
1062+ time timestamptz NOT NULL,
1063+ device int,
1064+ temp float8,
1065+ val int
1066+ );
1067+ SELECT create_hypertable('merge_sparse_order', 'time', chunk_time_interval => INTERVAL '1 day');
1068+ create_hypertable
1069+ ----------------------------------
1070+ (11,public,merge_sparse_order,t)
1071+
1072+ INSERT INTO merge_sparse_order
1073+ SELECT t, (i % 10) + 1, random() * 100, (i * 7) % 13
1074+ FROM generate_series('2024-01-01 2:00'::timestamptz, '2024-01-01 23:59', '1 minute') t,
1075+ generate_series(1, 5) i;
1076+ INSERT INTO merge_sparse_order
1077+ SELECT t, (i % 10) + 1, random() * 100, (i * 7) % 13
1078+ FROM generate_series('2024-01-02 2:00'::timestamptz, '2024-01-02 23:59', '1 minute') t,
1079+ generate_series(1, 5) i;
1080+ SELECT format('%I.%I', schema_name, table_name) AS mso_c1
1081+ FROM _timescaledb_catalog.chunk
1082+ WHERE hypertable_id = (SELECT id FROM _timescaledb_catalog.hypertable
1083+ WHERE table_name = 'merge_sparse_order')
1084+ ORDER BY id LIMIT 1 \gset
1085+ SELECT format('%I.%I', schema_name, table_name) AS mso_c2
1086+ FROM _timescaledb_catalog.chunk
1087+ WHERE hypertable_id = (SELECT id FROM _timescaledb_catalog.hypertable
1088+ WHERE table_name = 'merge_sparse_order')
1089+ ORDER BY id OFFSET 1 LIMIT 1 \gset
1090+ ALTER TABLE merge_sparse_order SET (
1091+ timescaledb.compress,
1092+ timescaledb.compress_orderby = 'time',
1093+ timescaledb.compress_index = 'bloom("device"), minmax("temp"), bloom("device","val")'
1094+ );
1095+ SELECT compress_chunk(:'mso_c1');
1096+ compress_chunk
1097+ ------------------------------------------
1098+ _timescaledb_internal._hyper_11_32_chunk
1099+
1100+ ALTER TABLE merge_sparse_order SET (
1101+ timescaledb.compress,
1102+ timescaledb.compress_orderby = 'time',
1103+ timescaledb.compress_index = 'minmax("temp"), bloom("device")'
1104+ );
1105+ NOTICE: updated compression settings will only apply to future compressions
1106+ SELECT compress_chunk(:'mso_c2');
1107+ compress_chunk
1108+ ------------------------------------------
1109+ _timescaledb_internal._hyper_11_33_chunk
1110+
1111+ -- have different sparse indexes
1112+ SELECT relid, index FROM _timescaledb_catalog.compression_settings ORDER BY relid::text;
1113+ relid | index
1114+ ------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1115+ _timescaledb_internal._hyper_1_1_chunk | [{"type": "minmax", "column": "time", "source": "orderby"}]
1116+ _timescaledb_internal._hyper_11_32_chunk | [{"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": ["device", "val"], "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1117+ _timescaledb_internal._hyper_11_33_chunk | [{"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1118+ merge_sparse_order | [{"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1119+ mergeme | [{"type": "minmax", "column": "time", "source": "orderby"}]
1120+
1121+ -- Merge should not succeed
1122+ \set ON_ERROR_STOP 0
1123+ CALL merge_chunks(:'mso_c1'::regclass, :'mso_c2'::regclass);
1124+ ERROR: cannot merge compressed chunks with different compression settings
1125+ \set ON_ERROR_STOP 1
1126+ ALTER TABLE merge_sparse_order SET (
1127+ timescaledb.compress,
1128+ timescaledb.compress_orderby = 'time',
1129+ timescaledb.compress_index = 'bloom("val","device"), minmax("temp"), bloom("device")'
1130+ );
1131+ NOTICE: updated compression settings will only apply to future compressions
1132+ SELECT compress_chunk(decompress_chunk(:'mso_c2'));
1133+ compress_chunk
1134+ ------------------------------------------
1135+ _timescaledb_internal._hyper_11_33_chunk
1136+
1137+ -- have different JSONB but same logical sparse indexes
1138+ SELECT relid, index FROM _timescaledb_catalog.compression_settings ORDER BY relid::text;
1139+ relid | index
1140+ ------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1141+ _timescaledb_internal._hyper_1_1_chunk | [{"type": "minmax", "column": "time", "source": "orderby"}]
1142+ _timescaledb_internal._hyper_11_32_chunk | [{"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": ["device", "val"], "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1143+ _timescaledb_internal._hyper_11_33_chunk | [{"type": "bloom", "column": ["device", "val"], "source": "config"}, {"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1144+ merge_sparse_order | [{"type": "bloom", "column": ["device", "val"], "source": "config"}, {"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1145+ mergeme | [{"type": "minmax", "column": "time", "source": "orderby"}]
1146+
1147+ -- Merge should succeed
1148+ CALL merge_chunks(:'mso_c1'::regclass, :'mso_c2'::regclass);
1149+ SELECT relid, index FROM _timescaledb_catalog.compression_settings ORDER BY relid::text;
1150+ relid | index
1151+ ------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1152+ _timescaledb_internal._hyper_1_1_chunk | [{"type": "minmax", "column": "time", "source": "orderby"}]
1153+ _timescaledb_internal._hyper_11_32_chunk | [{"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": ["device", "val"], "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1154+ merge_sparse_order | [{"type": "bloom", "column": ["device", "val"], "source": "config"}, {"type": "minmax", "column": "temp", "source": "config"}, {"type": "bloom", "column": "device", "source": "config"}, {"type": "minmax", "column": "time", "source": "orderby"}]
1155+ mergeme | [{"type": "minmax", "column": "time", "source": "orderby"}]
1156+
1157+ DROP TABLE merge_sparse_order;
0 commit comments