Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion tsl/src/compression/compression_dml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,8 @@ decompress_batches_scan(Relation in_rel, Relation out_rel, Relation index_rel, S
*/
for (; attrno >= 0; attrno = bms_next_member(null_columns, attrno))
{
is_null_condition = is_nulls && list_nth_int(is_nulls, pos);
// We cannot filter out NULLs if the unique constraint has NULLS NOT DISTINCT
is_null_condition = (is_nulls && list_nth_int(is_nulls, pos)) || (constraints && constraints->nullsnotdistinct);
seg_col_is_null = slot_attisnull(slot, attrno);
if ((seg_col_is_null && !is_null_condition) || (!seg_col_is_null && is_null_condition))
{
Expand Down
25 changes: 25 additions & 0 deletions tsl/test/shared/expected/compression_nulls_not_distinct.out
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,30 @@ ERROR: duplicate key value violates unique constraint "_hyper_X_X_chunk_nulls_n
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.5', 'd2', 'l1', 1);
INFO: Using index scan with scan keys: index 1, heap 4, memory 2.
INFO: Number of compressed rows fetched from index: 1. Number of compressed rows filtered by heap filters: 0.
-- test that this is correctly handled when using table scan
-- see https://github.com/timescale/timescaledb/issues/10057
SELECT count(compress_chunk(c)) FROM show_chunks('nulls_not_distinct') c;
INFO: Using index "compress_hyper_X_X_chunk_device__ts_meta_v2_last_time__ts_idx" for recompression
count
-------
1

set timescaledb.enable_dml_decompression_tuple_filtering to off;
-- should not insert a duplicate, conflict with existing (NULL, 'l1') row
\set ON_ERROR_STOP 0
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.5', NULL, 'l1', 1);
INFO: Using table scan with scan keys: index 0, heap 4, memory 0.
INFO: Number of compressed rows fetched from table scan: 2. Number of compressed rows filtered: 1.
ERROR: duplicate key value violates unique constraint "_hyper_X_X_chunk_nulls_not_distinct_time_device_label_idx"
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.5', 'd2', NULL, 1);
INFO: Using table scan with scan keys: index 0, heap 3, memory 0.
INFO: Number of compressed rows fetched from table scan: 1. Number of compressed rows filtered: 0.
ERROR: duplicate key value violates unique constraint "_hyper_X_X_chunk_nulls_not_distinct_time_device_label_idx"
\set ON_ERROR_STOP 1
-- should insert without error, no conflict
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.15', 'd2', 'l1', 1);
INFO: Using table scan with scan keys: index 0, heap 5, memory 0.
INFO: Number of compressed rows fetched from table scan: 1. Number of compressed rows filtered: 0.
RESET timescaledb.enable_dml_decompression_tuple_filtering;
RESET timescaledb.debug_compression_path_info;
DROP TABLE nulls_not_distinct;
15 changes: 15 additions & 0 deletions tsl/test/shared/sql/compression_nulls_not_distinct.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,20 @@ INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.5', 'd2', NULL, 1);
-- should insert without error, no conflict
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.5', 'd2', 'l1', 1);

-- test that this is correctly handled when using table scan
-- see https://github.com/timescale/timescaledb/issues/10057
SELECT count(compress_chunk(c)) FROM show_chunks('nulls_not_distinct') c;
set timescaledb.enable_dml_decompression_tuple_filtering to off;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kinda feels weird. Could we add a test case where we drop the compressed chunk index and test that works correctly now as well? Reading the issue seems that also caused the issue.


-- should not insert a duplicate, conflict with existing (NULL, 'l1') row
\set ON_ERROR_STOP 0
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.5', NULL, 'l1', 1);
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.5', 'd2', NULL, 1);
\set ON_ERROR_STOP 1

-- should insert without error, no conflict
INSERT INTO nulls_not_distinct VALUES ('2024-01-01 0:00:00.15', 'd2', 'l1', 1);

RESET timescaledb.enable_dml_decompression_tuple_filtering;
RESET timescaledb.debug_compression_path_info;
DROP TABLE nulls_not_distinct;
Loading