Skip to content

Commit

Permalink
Fix handling of chunks with no contraints
Browse files Browse the repository at this point in the history
When a catalog corruption occurs, and a chunk does not contain any
dimension slices, we crash in ts_dimension_slice_cmp(). This patch adds
a proper check and errors out before the code path is called.
  • Loading branch information
jnidzwetzki committed Apr 10, 2024
1 parent ea22843 commit c4ebdf6
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions .unreleased/fix_6816
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixes: #6816 Fix handling of chunks with no contraints
8 changes: 8 additions & 0 deletions src/chunk_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ ts_chunk_scan_by_chunk_ids(const Hyperspace *hs, const List *chunk_ids, unsigned
Assert(cube->capacity > cube->num_slices);
cube->slices[cube->num_slices++] = slice_copy;
}

if (cube->num_slices == 0)
{
ereport(ERROR,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("chunk %s has no dimension slices", get_rel_name(chunk->table_id))));
}

ts_hypercube_slice_sort(cube);
chunk->cube = cube;
}
Expand Down
30 changes: 30 additions & 0 deletions test/expected/catalog_corruption.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.
\c :TEST_DBNAME :ROLE_SUPERUSER
--- Test handling of missing dimension slices
CREATE TABLE dim_test(time TIMESTAMPTZ, device int);
SELECT create_hypertable('dim_test', 'time', chunk_time_interval => INTERVAL '1 day');
NOTICE: adding not-null constraint to column "time"
create_hypertable
-----------------------
(1,public,dim_test,t)
(1 row)

-- Create two chunks
INSERT INTO dim_test values('2000-01-01 00:00:00', 1);
INSERT INTO dim_test values('2020-01-01 00:00:00', 1);
SELECT id AS dim_slice_id FROM _timescaledb_catalog.dimension_slice
ORDER BY id DESC LIMIT 1
\gset
-- Delete the dimension slice for the second chunk
DELETE FROM _timescaledb_catalog.chunk_constraint WHERE dimension_slice_id = :dim_slice_id;
\set ON_ERROR_STOP 0
-- Select data
SELECT * FROM dim_test;
ERROR: chunk _hyper_1_2_chunk has no dimension slices
-- Select data using ordered append
SELECT * FROM dim_test ORDER BY time;
ERROR: chunk _hyper_1_2_chunk has no dimension slices
\set ON_ERROR_STOP 1
DROP TABLE dim_test;
1 change: 1 addition & 0 deletions test/sql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(TEST_FILES
alter.sql
alternate_users.sql
baserel_cache.sql
catalog_corruption.sql
chunks.sql
chunk_adaptive.sql
chunk_utils.sql
Expand Down
33 changes: 33 additions & 0 deletions test/sql/catalog_corruption.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.

\c :TEST_DBNAME :ROLE_SUPERUSER

--- Test handling of missing dimension slices
CREATE TABLE dim_test(time TIMESTAMPTZ, device int);
SELECT create_hypertable('dim_test', 'time', chunk_time_interval => INTERVAL '1 day');

-- Create two chunks
INSERT INTO dim_test values('2000-01-01 00:00:00', 1);
INSERT INTO dim_test values('2020-01-01 00:00:00', 1);

SELECT id AS dim_slice_id FROM _timescaledb_catalog.dimension_slice
ORDER BY id DESC LIMIT 1
\gset

-- Delete the dimension slice for the second chunk
DELETE FROM _timescaledb_catalog.chunk_constraint WHERE dimension_slice_id = :dim_slice_id;

\set ON_ERROR_STOP 0

-- Select data
SELECT * FROM dim_test;

-- Select data using ordered append
SELECT * FROM dim_test ORDER BY time;

\set ON_ERROR_STOP 1

DROP TABLE dim_test;

0 comments on commit c4ebdf6

Please sign in to comment.