From 9e1c200fef637d38d98f18cd9f0a89c5a1d2631f Mon Sep 17 00:00:00 2001 From: Keyur Panchal Date: Tue, 24 Dec 2024 08:59:59 -0700 Subject: [PATCH] Add hint when hypertable creation fails 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. --- .unreleased/pr_7565 | 2 ++ src/indexing.c | 5 ++++- test/expected/create_hypertable.out | 16 ++++++++++++++++ test/sql/create_hypertable.sql | 14 ++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .unreleased/pr_7565 diff --git a/.unreleased/pr_7565 b/.unreleased/pr_7565 new file mode 100644 index 00000000000..1dde2c8222b --- /dev/null +++ b/.unreleased/pr_7565 @@ -0,0 +1,2 @@ +Implements: #7565 Add hint when hypertable creation fails +Thanks: @k-rus for suggesting the improvement diff --git a/src/indexing.c b/src/indexing.c index 43c87395547..72ef91480c0 100644 --- a/src/indexing.c +++ b/src/indexing.c @@ -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."))); } } diff --git a/test/expected/create_hypertable.out b/test/expected/create_hypertable.out index 11c01e51d71..15b4e1320bd 100644 --- a/test/expected/create_hypertable.out +++ b/test/expected/create_hypertable.out @@ -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; diff --git a/test/sql/create_hypertable.sql b/test/sql/create_hypertable.sql index 62a1ca7adc3..6d8578dd94f 100644 --- a/test/sql/create_hypertable.sql +++ b/test/sql/create_hypertable.sql @@ -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;