mirror of
https://github.com/timescale/timescaledb.git
synced 2025-04-20 03:21:15 +08:00
Validate existing indexes before adding a new dimension
If the argument column of add_dimension is not in all of hypertable indexes that have UNIQUE, PRIMARY KEY or EXCLUSION constraints, then add_dimension call should fail. This commit enforces the above.
This commit is contained in:
parent
005813da21
commit
ed379c3dd8
@ -17,6 +17,7 @@
|
||||
#include "dimension.h"
|
||||
#include "dimension_slice.h"
|
||||
#include "hypertable.h"
|
||||
#include "indexing.h"
|
||||
#include "hypertable_cache.h"
|
||||
#include "partitioning.h"
|
||||
#include "scanner.h"
|
||||
@ -1004,6 +1005,16 @@ dimension_add(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
hypertable_set_num_dimensions(info.ht, info.ht->space->num_dimensions + 1);
|
||||
dimension_add_from_info(&info);
|
||||
|
||||
/* Verify that existing indexes are compatible with a hypertable */
|
||||
|
||||
/*
|
||||
* Need to get a fresh copy of hypertable from the database as cache
|
||||
* does not reflect the changes in the previous 2 lines which add a
|
||||
* new dimenison
|
||||
*/
|
||||
info.ht = hypertable_get_by_id(info.ht->fd.id);
|
||||
indexing_verify_indexes(info.ht);
|
||||
}
|
||||
|
||||
cache_release(hcache);
|
||||
|
@ -194,3 +194,70 @@ SELECT * FROM test.show_subtables('part_custom_func');
|
||||
_timescaledb_internal._hyper_5_7_chunk |
|
||||
(2 rows)
|
||||
|
||||
-- Test that index creation is handled correctly.
|
||||
CREATE TABLE hyper_with_index(time timestamptz, temp float, device int);
|
||||
CREATE UNIQUE INDEX temp_index ON hyper_with_index(temp);
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT create_hypertable('hyper_with_index', 'time');
|
||||
NOTICE: adding not-null constraint to column "time"
|
||||
ERROR: cannot create a unique index without the column "time" (used in partitioning)
|
||||
SELECT create_hypertable('hyper_with_index', 'time', 'device', 2);
|
||||
NOTICE: adding not-null constraint to column "time"
|
||||
ERROR: cannot create a unique index without the column "time" (used in partitioning)
|
||||
SELECT create_hypertable('hyper_with_index', 'time', 'temp', 2);
|
||||
NOTICE: adding not-null constraint to column "time"
|
||||
ERROR: cannot create a unique index without the column "time" (used in partitioning)
|
||||
\set ON_ERROR_STOP 1
|
||||
DROP INDEX temp_index;
|
||||
CREATE UNIQUE INDEX time_index ON hyper_with_index(time);
|
||||
\set ON_ERROR_STOP 0
|
||||
-- should error because device not in index
|
||||
SELECT create_hypertable('hyper_with_index', 'time', 'device', 4);
|
||||
NOTICE: adding not-null constraint to column "time"
|
||||
ERROR: cannot create a unique index without the column "device" (used in partitioning)
|
||||
\set ON_ERROR_STOP 1
|
||||
SELECT create_hypertable('hyper_with_index', 'time');
|
||||
NOTICE: adding not-null constraint to column "time"
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- make sure user created index is used.
|
||||
-- not using \d or \d+ because output syntax differs
|
||||
-- between postgres 9 and postgres 10.
|
||||
SELECT indexname FROM pg_indexes WHERE tablename = 'hyper_with_index';
|
||||
indexname
|
||||
------------
|
||||
time_index
|
||||
(1 row)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT add_dimension('hyper_with_index', 'device', 4);
|
||||
ERROR: cannot create a unique index without the column "device" (used in partitioning)
|
||||
\set ON_ERROR_STOP 1
|
||||
DROP INDEX time_index;
|
||||
CREATE UNIQUE INDEX time_space_index ON hyper_with_index(time, device);
|
||||
SELECT add_dimension('hyper_with_index', 'device', 4);
|
||||
add_dimension
|
||||
---------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE hyper_with_primary(time TIMESTAMPTZ PRIMARY KEY, temp float, device int);
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT create_hypertable('hyper_with_primary', 'time', 'device', 4);
|
||||
ERROR: cannot create a unique index without the column "device" (used in partitioning)
|
||||
\set ON_ERROR_STOP 1
|
||||
SELECT create_hypertable('hyper_with_primary', 'time');
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT add_dimension('hyper_with_primary', 'device', 4);
|
||||
ERROR: cannot create a unique index without the column "device" (used in partitioning)
|
||||
\set ON_ERROR_STOP 1
|
||||
-- NON-unique indexes can still be created
|
||||
CREATE INDEX temp_index ON hyper_with_index(temp);
|
||||
|
@ -83,3 +83,46 @@ INSERT INTO part_custom_func VALUES ('2017-03-22T09:18:23', 23.4, 'dev1'),
|
||||
('2017-03-22T09:18:23', 23.4, 'dev7');
|
||||
|
||||
SELECT * FROM test.show_subtables('part_custom_func');
|
||||
-- Test that index creation is handled correctly.
|
||||
CREATE TABLE hyper_with_index(time timestamptz, temp float, device int);
|
||||
CREATE UNIQUE INDEX temp_index ON hyper_with_index(temp);
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT create_hypertable('hyper_with_index', 'time');
|
||||
SELECT create_hypertable('hyper_with_index', 'time', 'device', 2);
|
||||
SELECT create_hypertable('hyper_with_index', 'time', 'temp', 2);
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
DROP INDEX temp_index;
|
||||
CREATE UNIQUE INDEX time_index ON hyper_with_index(time);
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
-- should error because device not in index
|
||||
SELECT create_hypertable('hyper_with_index', 'time', 'device', 4);
|
||||
\set ON_ERROR_STOP 1
|
||||
SELECT create_hypertable('hyper_with_index', 'time');
|
||||
-- make sure user created index is used.
|
||||
-- not using \d or \d+ because output syntax differs
|
||||
-- between postgres 9 and postgres 10.
|
||||
SELECT indexname FROM pg_indexes WHERE tablename = 'hyper_with_index';
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT add_dimension('hyper_with_index', 'device', 4);
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
DROP INDEX time_index;
|
||||
CREATE UNIQUE INDEX time_space_index ON hyper_with_index(time, device);
|
||||
SELECT add_dimension('hyper_with_index', 'device', 4);
|
||||
|
||||
|
||||
CREATE TABLE hyper_with_primary(time TIMESTAMPTZ PRIMARY KEY, temp float, device int);
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT create_hypertable('hyper_with_primary', 'time', 'device', 4);
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
SELECT create_hypertable('hyper_with_primary', 'time');
|
||||
\set ON_ERROR_STOP 0
|
||||
SELECT add_dimension('hyper_with_primary', 'device', 4);
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
-- NON-unique indexes can still be created
|
||||
CREATE INDEX temp_index ON hyper_with_index(temp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user