Cannot add dimension if table has empty chunks

add_dimension should fail when table has no
data but still has empty chunks.
Fixes #1623
This commit is contained in:
gayyappan 2020-01-31 10:46:36 -05:00 committed by gayyappan
parent 1880196ab4
commit 2702140fa3
6 changed files with 38 additions and 5 deletions

View File

@ -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**

View File

@ -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

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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".*