Skip to content

Commit

Permalink
Add hint when hypertable creation fails
Browse files Browse the repository at this point in the history
When creating a hypertable, we create default indexes on the partition
column, which requires that the column be a part of the table's primary
or composite key. The error message shown to the user in this scenario
did not indicate this correctly. This adds a hint to make this clearer.

Closes #2907.
  • Loading branch information
kpan2034 committed Dec 24, 2024
1 parent 27c4c02 commit de0028f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .unreleased/pr_7565
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Implements: #7565 Add hint when hypertable creation fails
Thanks: @k-rus for suggesting the improvement
5 changes: 4 additions & 1 deletion src/indexing.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ ts_indexing_verify_columns(const Hyperspace *hs, const List *indexelems)
(errcode(ERRCODE_TS_BAD_HYPERTABLE_INDEX_DEFINITION),
errmsg("cannot create a unique index without the column \"%s\" (used in "
"partitioning)",
NameStr(dim->fd.column_name))));
NameStr(dim->fd.column_name)),
errhint(
"If you're creating a hypertable on a table with a primary key, ensure "
"the partitioning column is part of the primary or composite key.")));
}
}

Expand Down
16 changes: 16 additions & 0 deletions test/expected/create_hypertable.out
Original file line number Diff line number Diff line change
Expand Up @@ -1121,3 +1121,19 @@ SELECT * FROM show_chunks('test') ch, LATERAL test.show_indexes(ch) ORDER BY 1,
_timescaledb_internal._hyper_25_24_chunk | _timescaledb_internal._hyper_25_24_chunk_test_val_idx | {val} | | f | f | f |
(1 row)

-- test creating a hypertable with a primary key where the partitioning column is not part of the primary key
CREATE TABLE test_schema.partition_not_pk (id INT NOT NULL, device_id INT NOT NULL, time TIMESTAMPTZ NOT NULL, a TEXT NOT NULL, PRIMARY KEY (id));
\set ON_ERROR_STOP 0
select create_hypertable ('test_schema.partition_not_pk', 'time');
ERROR: cannot create a unique index without the column "time" (used in partitioning)
HINT: If you're creating a hypertable on a table with a primary key, ensure the partitioning column is part of the primary or composite key.
\set ON_ERROR_STOP 1
DROP TABLE test_schema.partition_not_pk;
-- test creating a hypertable with a composite key where the partitioning column is not part of the composite key
CREATE TABLE test_schema.partition_not_pk (id INT NOT NULL, device_id INT NOT NULL, time TIMESTAMPTZ NOT NULL, a TEXT NOT NULL, PRIMARY KEY (id, device_id));
\set ON_ERROR_STOP 0
select create_hypertable ('test_schema.partition_not_pk', 'time');
ERROR: cannot create a unique index without the column "time" (used in partitioning)
HINT: If you're creating a hypertable on a table with a primary key, ensure the partitioning column is part of the primary or composite key.
\set ON_ERROR_STOP 1
DROP TABLE test_schema.partition_not_pk;
14 changes: 14 additions & 0 deletions test/sql/create_hypertable.sql
Original file line number Diff line number Diff line change
Expand Up @@ -666,3 +666,17 @@ SELECT FROM create_hypertable('test', 'time', create_default_indexes => FALSE, m
-- only user indexes should be returned
SELECT * FROM test.show_indexes('test') ORDER BY 1;
SELECT * FROM show_chunks('test') ch, LATERAL test.show_indexes(ch) ORDER BY 1, 2;

-- test creating a hypertable with a primary key where the partitioning column is not part of the primary key
CREATE TABLE test_schema.partition_not_pk (id INT NOT NULL, device_id INT NOT NULL, time TIMESTAMPTZ NOT NULL, a TEXT NOT NULL, PRIMARY KEY (id));
\set ON_ERROR_STOP 0
select create_hypertable ('test_schema.partition_not_pk', 'time');
\set ON_ERROR_STOP 1
DROP TABLE test_schema.partition_not_pk;

-- test creating a hypertable with a composite key where the partitioning column is not part of the composite key
CREATE TABLE test_schema.partition_not_pk (id INT NOT NULL, device_id INT NOT NULL, time TIMESTAMPTZ NOT NULL, a TEXT NOT NULL, PRIMARY KEY (id, device_id));
\set ON_ERROR_STOP 0
select create_hypertable ('test_schema.partition_not_pk', 'time');
\set ON_ERROR_STOP 1
DROP TABLE test_schema.partition_not_pk;

0 comments on commit de0028f

Please sign in to comment.