mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-19 20:24:46 +08:00
Adding a constraint using an existing index changes the existing index's name as a side effect (PostgreSQL wants the index name to match the constraint name). This creates a mismatch between the index's name and our metadata in the chunk_index table. Further, since the name change happens as a result of an internal command (and not via DDL command that we can capture) there is currently no way to sync up this information.
310 lines
8.7 KiB
SQL
310 lines
8.7 KiB
SQL
\o /dev/null
|
|
\ir include/create_single_db.sql
|
|
\o
|
|
|
|
CREATE TABLE hyper (
|
|
time BIGINT NOT NULL,
|
|
device_id TEXT NOT NULL,
|
|
sensor_1 NUMERIC NULL DEFAULT 1 CHECK (sensor_1 > 10)
|
|
);
|
|
|
|
|
|
SELECT * FROM create_hypertable('hyper', 'time', chunk_time_interval => 10);
|
|
|
|
--check and not-null constraints are inherited through regular inheritance.
|
|
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 9);
|
|
|
|
INSERT INTO hyper(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, NULL, 11);
|
|
|
|
\set ON_ERROR_STOP 1
|
|
|
|
INSERT INTO hyper(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
|
|
INSERT INTO hyper(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
|
|
----------------------- UNIQUE CONSTRAINTS ------------------
|
|
|
|
CREATE TABLE hyper_unique (
|
|
time BIGINT NOT NULL UNIQUE,
|
|
device_id TEXT NOT NULL,
|
|
sensor_1 NUMERIC NULL DEFAULT 1 CHECK (sensor_1 > 10)
|
|
);
|
|
|
|
|
|
SELECT * FROM create_hypertable('hyper_unique', 'time', chunk_time_interval => 10);
|
|
|
|
INSERT INTO hyper_unique(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
|
|
INSERT INTO hyper_unique(time, device_id,sensor_1) VALUES
|
|
(1257987800000000000, 'dev2', 11);
|
|
|
|
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_unique(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
\d+ hyper
|
|
\d+ hyper_unique
|
|
--should have unique constraint not just unique index
|
|
\d+ _timescaledb_internal._hyper_2_4_chunk
|
|
|
|
ALTER TABLE hyper_unique DROP CONSTRAINT hyper_unique_time_key;
|
|
\d+ _timescaledb_internal._hyper_2_4_chunk
|
|
|
|
--uniqueness not enforced
|
|
INSERT INTO hyper_unique(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev3', 11);
|
|
|
|
--shouldn't be able to create constraint
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper_unique ADD CONSTRAINT hyper_unique_time_key UNIQUE (time);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
DELETE FROM hyper_unique WHERE device_id = 'dev3';
|
|
|
|
-- Try adding constraint using existing index
|
|
CREATE UNIQUE INDEX ON hyper_unique (time);
|
|
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper_unique ADD CONSTRAINT hyper_unique_time_key UNIQUE USING INDEX hyper_unique_time_idx;
|
|
\set ON_ERROR_STOP 1
|
|
|
|
DROP INDEX hyper_unique_time_idx;
|
|
|
|
--now can create
|
|
ALTER TABLE hyper_unique ADD CONSTRAINT hyper_unique_time_key UNIQUE (time);
|
|
\d+ _timescaledb_internal._hyper_2_4_chunk
|
|
|
|
--test adding constraint with same name to different table -- should fail
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper ADD CONSTRAINT hyper_unique_time_key UNIQUE (time);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
--uniquness violation fails
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_unique(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
--cannot create unique constraint on non-partition column
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper_unique ADD CONSTRAINT hyper_unique_invalid UNIQUE (device_id);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
|
|
----------------------- PRIMARY KEY ------------------
|
|
|
|
CREATE TABLE hyper_pk (
|
|
time BIGINT NOT NULL PRIMARY KEY,
|
|
device_id TEXT NOT NULL,
|
|
sensor_1 NUMERIC NULL DEFAULT 1 CHECK (sensor_1 > 10)
|
|
);
|
|
|
|
|
|
SELECT * FROM create_hypertable('hyper_pk', 'time', chunk_time_interval => 10);
|
|
|
|
INSERT INTO hyper_pk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_pk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
--should have unique constraint not just unique index
|
|
\d+ _timescaledb_internal._hyper_3_6_chunk
|
|
|
|
ALTER TABLE hyper_pk DROP CONSTRAINT hyper_pk_pkey;
|
|
\d+ _timescaledb_internal._hyper_3_6_chunk
|
|
|
|
--uniqueness not enforced
|
|
INSERT INTO hyper_pk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev3', 11);
|
|
|
|
|
|
--shouldn't be able to create pk
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper_pk ADD CONSTRAINT hyper_pk_pkey PRIMARY KEY (time);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
DELETE FROM hyper_pk WHERE device_id = 'dev3';
|
|
|
|
--cannot create pk constraint on non-partition column
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper_pk ADD CONSTRAINT hyper_pk_invalid PRIMARY KEY (device_id);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
--now can create
|
|
ALTER TABLE hyper_pk ADD CONSTRAINT hyper_pk_pkey PRIMARY KEY (time);
|
|
\d+ _timescaledb_internal._hyper_3_6_chunk
|
|
|
|
--test adding constraint with same name to different table -- should fail
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper ADD CONSTRAINT hyper_pk_pkey UNIQUE (time);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
--uniquness violation fails
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_pk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
|
|
----------------------- FOREIGN KEY ------------------
|
|
|
|
CREATE TABLE devices(
|
|
device_id TEXT NOT NULL,
|
|
PRIMARY KEY (device_id)
|
|
);
|
|
|
|
CREATE TABLE hyper_fk (
|
|
time BIGINT NOT NULL PRIMARY KEY,
|
|
device_id TEXT NOT NULL REFERENCES devices(device_id),
|
|
sensor_1 NUMERIC NULL DEFAULT 1 CHECK (sensor_1 > 10)
|
|
);
|
|
|
|
|
|
SELECT * FROM create_hypertable('hyper_fk', 'time', chunk_time_interval => 10);
|
|
|
|
--fail fk constraint
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_fk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
INSERT INTO devices VALUES ('dev2');
|
|
|
|
INSERT INTO hyper_fk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
|
|
--delete should fail
|
|
\set ON_ERROR_STOP 0
|
|
DELETE FROM devices;
|
|
\set ON_ERROR_STOP 1
|
|
|
|
ALTER TABLE hyper_fk DROP CONSTRAINT hyper_fk_device_id_fkey;
|
|
|
|
--should now be able to add non-fk rows
|
|
INSERT INTO hyper_fk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000001, 'dev3', 11);
|
|
|
|
--can't add fk because of dev3 row
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper_fk ADD CONSTRAINT hyper_fk_device_id_fkey
|
|
FOREIGN KEY (device_id) REFERENCES devices(device_id);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
DELETE FROM hyper_fk WHERE device_id = 'dev3';
|
|
|
|
ALTER TABLE hyper_fk ADD CONSTRAINT hyper_fk_device_id_fkey
|
|
FOREIGN KEY (device_id) REFERENCES devices(device_id);
|
|
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_fk(time, device_id,sensor_1) VALUES
|
|
(1257987700000000002, 'dev3', 11);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
----------------------- FOREIGN KEY INTO A HYPERTABLE ------------------
|
|
|
|
|
|
--FOREIGN KEY references into a hypertable are currently broken.
|
|
--The referencing table will never find the corresponding row in the hypertable
|
|
--since it will only search the parent. Thus any insert will result in an ERROR
|
|
--TODO: block such foreign keys or fix. (Hard to block on create table so punting for now)
|
|
CREATE TABLE hyper_for_ref (
|
|
time BIGINT NOT NULL PRIMARY KEY,
|
|
device_id TEXT NOT NULL,
|
|
sensor_1 NUMERIC NULL DEFAULT 1 CHECK (sensor_1 > 10)
|
|
);
|
|
|
|
SELECT * FROM create_hypertable('hyper_for_ref', 'time', chunk_time_interval => 10);
|
|
|
|
\set ON_ERROR_STOP 0
|
|
CREATE TABLE referrer (
|
|
time BIGINT NOT NULL REFERENCES hyper_for_ref(time)
|
|
);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
CREATE TABLE referrer2 (
|
|
time BIGINT NOT NULL
|
|
);
|
|
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE referrer2 ADD CONSTRAINT hyper_fk_device_id_fkey
|
|
FOREIGN KEY (time) REFERENCES hyper_for_ref(time);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
----------------------- EXCLUSION CONSTRAINT ------------------
|
|
|
|
CREATE TABLE hyper_ex (
|
|
time BIGINT,
|
|
device_id TEXT NOT NULL REFERENCES devices(device_id),
|
|
sensor_1 NUMERIC NULL DEFAULT 1 CHECK (sensor_1 > 10),
|
|
canceled boolean DEFAULT false,
|
|
EXCLUDE USING btree (
|
|
time WITH =, device_id WITH =
|
|
) WHERE (not canceled)
|
|
);
|
|
|
|
SELECT * FROM create_hypertable('hyper_ex', 'time', chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'));
|
|
|
|
INSERT INTO hyper_ex(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 11);
|
|
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_ex(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 12);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
ALTER TABLE hyper_ex DROP CONSTRAINT hyper_ex_time_device_id_excl;
|
|
|
|
--can now add
|
|
INSERT INTO hyper_ex(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 12);
|
|
|
|
--cannot add because of conflicts
|
|
\set ON_ERROR_STOP 0
|
|
ALTER TABLE hyper_ex ADD CONSTRAINT hyper_ex_time_device_id_excl
|
|
EXCLUDE USING btree (
|
|
time WITH =, device_id WITH =
|
|
) WHERE (not canceled)
|
|
;
|
|
\set ON_ERROR_STOP 1
|
|
|
|
DELETE FROM hyper_ex WHERE sensor_1 = 12;
|
|
|
|
ALTER TABLE hyper_ex ADD CONSTRAINT hyper_ex_time_device_id_excl
|
|
EXCLUDE USING btree (
|
|
time WITH =, device_id WITH =
|
|
) WHERE (not canceled)
|
|
;
|
|
|
|
\set ON_ERROR_STOP 0
|
|
INSERT INTO hyper_ex(time, device_id,sensor_1) VALUES
|
|
(1257987700000000000, 'dev2', 12);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
|
|
--cannot add exclusion constraint without partition key.
|
|
CREATE TABLE hyper_ex_invalid (
|
|
time BIGINT,
|
|
device_id TEXT NOT NULL REFERENCES devices(device_id),
|
|
sensor_1 NUMERIC NULL DEFAULT 1 CHECK (sensor_1 > 10),
|
|
canceled boolean DEFAULT false,
|
|
EXCLUDE USING btree (
|
|
device_id WITH =
|
|
) WHERE (not canceled)
|
|
);
|
|
|
|
\set ON_ERROR_STOP 0
|
|
SELECT * FROM create_hypertable('hyper_ex_invalid', 'time', chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'));
|
|
\set ON_ERROR_STOP 1
|