diff --git a/.unreleased/pr_7399 b/.unreleased/pr_7399 new file mode 100644 index 000000000..ff5454158 --- /dev/null +++ b/.unreleased/pr_7399 @@ -0,0 +1,2 @@ +Fixes: #7384 Fix using OIDs with bitmapsets +Thanks: @dx034 for reporting an issue with negative bitmapset members due to large OIDs diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.c b/tsl/src/nodes/decompress_chunk/decompress_chunk.c index 3fe42418d..393fb8117 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_chunk.c +++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.c @@ -157,7 +157,7 @@ append_ec_for_metadata_col(PlannerInfo *root, CompressionInfo *info, Var *var, P EquivalenceMember *em = makeNode(EquivalenceMember); em->em_expr = (Expr *) var; - em->em_relids = bms_make_singleton(info->compressed_rte->relid); + em->em_relids = bms_make_singleton(info->compressed_rel->relid); em->em_is_const = false; em->em_is_child = false; em->em_datatype = var->vartype; diff --git a/tsl/test/expected/compression_sequence_num_removal.out b/tsl/test/expected/compression_sequence_num_removal.out index 3f5e936c1..49c102455 100644 --- a/tsl/test/expected/compression_sequence_num_removal.out +++ b/tsl/test/expected/compression_sequence_num_removal.out @@ -353,7 +353,7 @@ FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.chunk comp_ch, _timesc WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper' AND ch1.compressed_chunk_id = comp_ch.id ORDER BY ch1.id LIMIT 1 \gset -\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER +SET ROLE :ROLE_CLUSTER_SUPERUSER; SET timescaledb.restoring TO ON; -- add sequence number column and fill in the correct sequences ALTER TABLE :CHUNK_FULL_NAME ADD COLUMN _ts_meta_sequence_num int; @@ -363,13 +363,13 @@ FROM :CHUNK_FULL_NAME ORDER BY _ts_meta_min_1, _ts_meta_max_1; DELETE FROM :CHUNK_FULL_NAME WHERE _ts_meta_sequence_num IS NULL; SET timescaledb.restoring TO OFF; -\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +SET ROLE :ROLE_DEFAULT_PERM_USER; SELECT comp_ch.table_name AS "CHUNK_NAME", comp_ch.schema_name|| '.' || comp_ch.table_name AS "CHUNK_FULL_NAME" FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.chunk comp_ch, _timescaledb_catalog.hypertable ht WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper' AND ch1.compressed_chunk_id = comp_ch.id ORDER BY ch1.id OFFSET 3 LIMIT 1 \gset -\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER +SET ROLE :ROLE_CLUSTER_SUPERUSER; SET timescaledb.restoring TO ON; -- add sequence number column and fill in the correct sequences ALTER TABLE :CHUNK_FULL_NAME ADD COLUMN _ts_meta_sequence_num int; @@ -378,7 +378,8 @@ SELECT device_id, time, val, _ts_meta_count, _ts_meta_min_1, _ts_meta_max_1 , 10 FROM :CHUNK_FULL_NAME ORDER BY _ts_meta_min_1, _ts_meta_max_1; DELETE FROM :CHUNK_FULL_NAME WHERE _ts_meta_sequence_num IS NULL; -\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +SET timescaledb.restoring TO OFF; +SET ROLE :ROLE_DEFAULT_PERM_USER; -- from this point, two chunks should use sequence numbers and the rest will work without them :EXPLAIN SELECT * FROM hyper ORDER BY time; @@ -443,3 +444,51 @@ NOTICE: chunk "_hyper_1_13_chunk" is already compressed _timescaledb_internal._hyper_1_18_chunk (6 rows) +-- gh issue #7384 +-- modifying compressed chunk OID to over INT32_MAX +-- to detect if we handle those properly +TRUNCATE hyper; +ALTER TABLE hyper SET ( + timescaledb.compress, + timescaledb.compress_orderby = 'time', + timescaledb.compress_segmentby = 'device_id'); +INSERT INTO hyper VALUES (1, 1, 1), (2, 2, 1), (3, 3, 1), (10, 3, 2), (11, 4, 2), (11, 5, 2), (21, 2, 3), (22, 3, 3), (23, 4, 3), (30, 1, 4), (31, 3, 4), (31, 5, 4); +SELECT compress_chunk(show_chunks('hyper')); + compress_chunk +----------------------------------------- + _timescaledb_internal._hyper_1_21_chunk + _timescaledb_internal._hyper_1_21_chunk + _timescaledb_internal._hyper_1_21_chunk + _timescaledb_internal._hyper_1_21_chunk +(4 rows) + +SELECT comp_ch.table_name AS "CHUNK_NAME", comp_ch.schema_name|| '.' || comp_ch.table_name AS "CHUNK_FULL_NAME" +FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.chunk comp_ch, _timescaledb_catalog.hypertable ht +WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper' +AND ch1.compressed_chunk_id = comp_ch.id +ORDER BY ch1.id LIMIT 1 \gset +SET ROLE :ROLE_CLUSTER_SUPERUSER; +SELECT :'CHUNK_FULL_NAME'::regclass::oid as "CHUNK_OID" \gset +SELECT (power(2,31)+1)::bigint as "CHUNK_NEW_OID" \gset +UPDATE pg_class SET oid = :CHUNK_NEW_OID +WHERE oid = :CHUNK_OID; +UPDATE pg_attribute SET attrelid = :CHUNK_NEW_OID +WHERE attrelid = :CHUNK_OID; +UPDATE _timescaledb_catalog.compression_settings SET relid = :CHUNK_NEW_OID +WHERE relid = :CHUNK_OID; +:EXPLAIN SELECT * FROM hyper +WHERE device_id = 1 ORDER BY time; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_21_chunk + Output: _hyper_1_21_chunk."time", _hyper_1_21_chunk.device_id, _hyper_1_21_chunk.val + -> Sort + Output: compress_hyper_2_25_chunk._ts_meta_count, compress_hyper_2_25_chunk.device_id, compress_hyper_2_25_chunk._ts_meta_min_1, compress_hyper_2_25_chunk._ts_meta_max_1, compress_hyper_2_25_chunk."time", compress_hyper_2_25_chunk.val + Sort Key: compress_hyper_2_25_chunk._ts_meta_min_1, compress_hyper_2_25_chunk._ts_meta_max_1 + -> Seq Scan on _timescaledb_internal.compress_hyper_2_25_chunk + Output: compress_hyper_2_25_chunk._ts_meta_count, compress_hyper_2_25_chunk.device_id, compress_hyper_2_25_chunk._ts_meta_min_1, compress_hyper_2_25_chunk._ts_meta_max_1, compress_hyper_2_25_chunk."time", compress_hyper_2_25_chunk.val + Filter: (compress_hyper_2_25_chunk.device_id = 1) +(8 rows) + +SET ROLE :ROLE_DEFAULT_PERM_USER; +DROP TABLE hyper; diff --git a/tsl/test/sql/compression_sequence_num_removal.sql b/tsl/test/sql/compression_sequence_num_removal.sql index 9c416d4a3..830d56d49 100644 --- a/tsl/test/sql/compression_sequence_num_removal.sql +++ b/tsl/test/sql/compression_sequence_num_removal.sql @@ -130,7 +130,7 @@ WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper' AND ch1.compressed_chunk_id = comp_ch.id ORDER BY ch1.id LIMIT 1 \gset -\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER +SET ROLE :ROLE_CLUSTER_SUPERUSER; SET timescaledb.restoring TO ON; -- add sequence number column and fill in the correct sequences ALTER TABLE :CHUNK_FULL_NAME ADD COLUMN _ts_meta_sequence_num int; @@ -140,7 +140,7 @@ FROM :CHUNK_FULL_NAME ORDER BY _ts_meta_min_1, _ts_meta_max_1; DELETE FROM :CHUNK_FULL_NAME WHERE _ts_meta_sequence_num IS NULL; SET timescaledb.restoring TO OFF; -\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +SET ROLE :ROLE_DEFAULT_PERM_USER; SELECT comp_ch.table_name AS "CHUNK_NAME", comp_ch.schema_name|| '.' || comp_ch.table_name AS "CHUNK_FULL_NAME" FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.chunk comp_ch, _timescaledb_catalog.hypertable ht @@ -148,7 +148,7 @@ WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper' AND ch1.compressed_chunk_id = comp_ch.id ORDER BY ch1.id OFFSET 3 LIMIT 1 \gset -\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER +SET ROLE :ROLE_CLUSTER_SUPERUSER; SET timescaledb.restoring TO ON; -- add sequence number column and fill in the correct sequences ALTER TABLE :CHUNK_FULL_NAME ADD COLUMN _ts_meta_sequence_num int; @@ -157,7 +157,8 @@ SELECT device_id, time, val, _ts_meta_count, _ts_meta_min_1, _ts_meta_max_1 , 10 FROM :CHUNK_FULL_NAME ORDER BY _ts_meta_min_1, _ts_meta_max_1; DELETE FROM :CHUNK_FULL_NAME WHERE _ts_meta_sequence_num IS NULL; -\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER +SET timescaledb.restoring TO OFF; +SET ROLE :ROLE_DEFAULT_PERM_USER; -- from this point, two chunks should use sequence numbers and the rest will work without them :EXPLAIN SELECT * FROM hyper @@ -175,3 +176,37 @@ INSERT INTO hyper VALUES (41, 1, 1), (42, 2, 1), (43, 3, 1), (50, 3, 2), (51, 4, -- and roll up the two new chunks into a single chunk SELECT compress_chunk(show_chunks('hyper')); + +-- gh issue #7384 +-- modifying compressed chunk OID to over INT32_MAX +-- to detect if we handle those properly +TRUNCATE hyper; +ALTER TABLE hyper SET ( + timescaledb.compress, + timescaledb.compress_orderby = 'time', + timescaledb.compress_segmentby = 'device_id'); +INSERT INTO hyper VALUES (1, 1, 1), (2, 2, 1), (3, 3, 1), (10, 3, 2), (11, 4, 2), (11, 5, 2), (21, 2, 3), (22, 3, 3), (23, 4, 3), (30, 1, 4), (31, 3, 4), (31, 5, 4); + +SELECT compress_chunk(show_chunks('hyper')); + +SELECT comp_ch.table_name AS "CHUNK_NAME", comp_ch.schema_name|| '.' || comp_ch.table_name AS "CHUNK_FULL_NAME" +FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.chunk comp_ch, _timescaledb_catalog.hypertable ht +WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper' +AND ch1.compressed_chunk_id = comp_ch.id +ORDER BY ch1.id LIMIT 1 \gset + +SET ROLE :ROLE_CLUSTER_SUPERUSER; +SELECT :'CHUNK_FULL_NAME'::regclass::oid as "CHUNK_OID" \gset +SELECT (power(2,31)+1)::bigint as "CHUNK_NEW_OID" \gset +UPDATE pg_class SET oid = :CHUNK_NEW_OID +WHERE oid = :CHUNK_OID; +UPDATE pg_attribute SET attrelid = :CHUNK_NEW_OID +WHERE attrelid = :CHUNK_OID; +UPDATE _timescaledb_catalog.compression_settings SET relid = :CHUNK_NEW_OID +WHERE relid = :CHUNK_OID; + +:EXPLAIN SELECT * FROM hyper +WHERE device_id = 1 ORDER BY time; +SET ROLE :ROLE_DEFAULT_PERM_USER; + +DROP TABLE hyper;