From 2702140fa37739ee262e752b3d66beb0f212a2b8 Mon Sep 17 00:00:00 2001 From: gayyappan Date: Fri, 31 Jan 2020 10:46:36 -0500 Subject: [PATCH] Cannot add dimension if table has empty chunks add_dimension should fail when table has no data but still has empty chunks. Fixes #1623 --- CHANGELOG.md | 1 + src/dimension.c | 8 +++++--- src/hypertable.c | 10 ++++++++++ src/hypertable.h | 1 + test/expected/create_hypertable.out | 16 ++++++++++++++-- test/sql/create_hypertable.sql | 7 +++++++ 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b09f339a..020c44788 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ accidentally triggering the load of a previous DB version.** **Bugfixes** * #1648 Drop chunks for materialized hypertable * #1665 Add ignore_invalidation_older_than to timescaledb_information.continuous_aggregates view +* #1668 Cannot add dimension if hypertable has empty chunks * #1674 Fix time_bucket_gapfill's interaction with GROUP BY **Thanks** diff --git a/src/dimension.c b/src/dimension.c index 2849051e0..abc949320 100644 --- a/src/dimension.c +++ b/src/dimension.c @@ -1355,11 +1355,13 @@ ts_dimension_add(PG_FUNCTION_ARGS) if (!info.skip) { - if (ts_hypertable_has_tuples(info.table_relid, AccessShareLock)) + if (ts_hypertable_has_chunks(info.table_relid, AccessShareLock)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("hypertable \"%s\" is not empty", get_rel_name(info.table_relid)), - errdetail("It is not possible to add dimensions to a non-empty hypertable"))); + errmsg("hypertable \"%s\" has tuples or empty chunks", + get_rel_name(info.table_relid)), + errdetail("It is not possible to add dimensions to a hypertable that has " + "chunks. Please truncate the table."))); /* * Note that space->num_dimensions reflects the actual number of diff --git a/src/hypertable.c b/src/hypertable.c index 280d53cbd..d685de5b7 100644 --- a/src/hypertable.c +++ b/src/hypertable.c @@ -1250,6 +1250,16 @@ ts_hypertable_has_tuples(Oid table_relid, LOCKMODE lockmode) return false; } +bool +ts_hypertable_has_chunks(Oid table_relid, LOCKMODE lockmode) +{ + List *chunks = find_inheritance_children(table_relid, lockmode); + if (chunks != NIL) + return true; + else + return false; +} + static void hypertable_create_schema(const char *schema_name) { diff --git a/src/hypertable.h b/src/hypertable.h index 493ffa57f..73165aa66 100644 --- a/src/hypertable.h +++ b/src/hypertable.h @@ -114,6 +114,7 @@ extern char *ts_hypertable_select_tablespace_name(Hypertable *ht, Chunk *chunk); extern Tablespace *ts_hypertable_get_tablespace_at_offset_from(int32 hypertable_id, Oid tablespace_oid, int16 offset); extern bool ts_hypertable_has_tuples(Oid table_relid, LOCKMODE lockmode); +extern bool ts_hypertable_has_chunks(Oid table_relid, LOCKMODE lockmode); extern void ts_hypertables_rename_schema_name(const char *old_name, const char *new_name); extern List *ts_hypertable_get_all_by_name(Name schema_name, Name table_name, MemoryContext mctx); extern bool ts_is_partitioning_column(Hypertable *ht, Index column_attno); diff --git a/test/expected/create_hypertable.out b/test/expected/create_hypertable.out index edc801a8d..08db66264 100644 --- a/test/expected/create_hypertable.out +++ b/test/expected/create_hypertable.out @@ -238,10 +238,10 @@ ERROR: cannot specify both the number of partitions and an interval --adding a new dimension on a non-empty table should also fail insert into test_schema.test_table values (123456789, 23.8, 'blue', 'type1', 'nyc', 1, 1); select add_dimension('test_schema.test_table', 'device_type', 2); -ERROR: hypertable "test_table" is not empty +ERROR: hypertable "test_table" has tuples or empty chunks -- should fail on non-empty table with 'if_not_exists' in case the dimension does not exists select add_dimension('test_schema.test_table', 'device_type', 2, if_not_exists => true); -ERROR: hypertable "test_table" is not empty +ERROR: hypertable "test_table" has tuples or empty chunks \set ON_ERROR_STOP 1 -- should not fail on non-empty table with 'if_not_exists' in case the dimension exists select add_dimension('test_schema.test_table', 'location', 2, if_not_exists => true); @@ -251,6 +251,18 @@ NOTICE: column "location" is already a dimension, skipping (5,test_schema,test_table,location,f) (1 row) +--should fail on empty table that still has chunks -- +\set ON_ERROR_STOP 0 +delete from test_schema.test_table where time is not null; +select count(*) from test_schema.test_table; + count +------- + 0 +(1 row) + +select add_dimension('test_schema.test_table', 'device_type', 2); +ERROR: hypertable "test_table" has tuples or empty chunks +\set ON_ERROR_STOP 1 --show chunks in the associated schema \dt "chunk_schema".* List of relations diff --git a/test/sql/create_hypertable.sql b/test/sql/create_hypertable.sql index 2e90bdd8c..70a4ce2a0 100644 --- a/test/sql/create_hypertable.sql +++ b/test/sql/create_hypertable.sql @@ -135,6 +135,13 @@ select add_dimension('test_schema.test_table', 'device_type', 2, if_not_exists = -- should not fail on non-empty table with 'if_not_exists' in case the dimension exists select add_dimension('test_schema.test_table', 'location', 2, if_not_exists => true); +--should fail on empty table that still has chunks -- +\set ON_ERROR_STOP 0 +delete from test_schema.test_table where time is not null; +select count(*) from test_schema.test_table; +select add_dimension('test_schema.test_table', 'device_type', 2); +\set ON_ERROR_STOP 1 + --show chunks in the associated schema \dt "chunk_schema".*