timescaledb/tsl/test/expected/foreign_keys.out
Sven Klemm 98668b8dea Sync FK behaviour when creating hypertable
We now allow FKs to hypertables but the initial check when creating
the hypertable was not adjusted so tables with pre-existing FKs
would not be allowed to be changed into hypertable while creating
the FK constraint afterwards succeeded.
2024-09-30 10:49:12 +02:00

1059 lines
47 KiB
Plaintext

-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
-- test single column fk constraint from plain table to hypertable during hypertable creation
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 0:00:00', 'd1', 1.0);
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 1:00:00', 'd1', 1.0);
CREATE TABLE event(time timestamptz references metrics(time), info text);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2020-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
\set ON_ERROR_STOP 0
-- should fail
UPDATE event SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
BEGIN;
UPDATE event SET time = '2020-01-01 01:00:00' WHERE time = '2020-01-01';
ROLLBACK;
\set ON_ERROR_STOP 0
-- should fail
DELETE FROM metrics WHERE time = '2020-01-01';
ERROR: update or delete on table "_hyper_1_1_chunk" violates foreign key constraint "event_time_fkey1" on table "event"
-- should fail
UPDATE metrics SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: update or delete on table "_hyper_1_1_chunk" violates foreign key constraint "event_time_fkey1" on table "event"
\set ON_ERROR_STOP 1
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_1_1_chunk | t
(2 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
------------------------+--------+--------------+---------------
"RI_FKey_noaction_del" | f | t | event
"RI_FKey_noaction_upd" | f | t | event
"RI_FKey_noaction_del" | t | t | event
"RI_FKey_noaction_upd" | t | t | event
(4 rows)
-- create new chunk and repeat the test
INSERT INTO metrics(time, device, value) VALUES ('2021-01-01', 'd1', 1.0);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2021-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2021-01-01', 'info2');
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_1_1_chunk | t
event_time_fkey2 | event | _timescaledb_internal._hyper_1_2_chunk | t
(3 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
------------------------+--------+--------------+---------------
"RI_FKey_noaction_del" | f | t | event
"RI_FKey_noaction_upd" | f | t | event
"RI_FKey_noaction_del" | t | t | event
"RI_FKey_noaction_upd" | t | t | event
"RI_FKey_noaction_del" | t | t | event
"RI_FKey_noaction_upd" | t | t | event
(6 rows)
-- chunks referenced in fk constraints must not be dropped or truncated
\set ON_ERROR_STOP 0
TRUNCATE metrics;
ERROR: cannot truncate a table referenced in a foreign key constraint
TRUNCATE _timescaledb_internal._hyper_1_1_chunk;
ERROR: cannot truncate a table referenced in a foreign key constraint
TRUNCATE _timescaledb_internal._hyper_1_2_chunk;
ERROR: cannot truncate a table referenced in a foreign key constraint
DROP TABLE _timescaledb_internal._hyper_1_1_chunk;
ERROR: cannot drop table _timescaledb_internal._hyper_1_1_chunk because other objects depend on it
DROP TABLE _timescaledb_internal._hyper_1_2_chunk;
ERROR: cannot drop table _timescaledb_internal._hyper_1_2_chunk because other objects depend on it
SELECT drop_chunks('metrics', '1 month'::interval);
ERROR: cannot drop constraint 1_1_metrics_pkey on table _timescaledb_internal._hyper_1_1_chunk because other objects depend on it
\set ON_ERROR_STOP 1
-- after removing constraint dropping should succeed
ALTER TABLE event DROP CONSTRAINT event_time_fkey;
SELECT drop_chunks('metrics', '1 month'::interval);
drop_chunks
----------------------------------------
_timescaledb_internal._hyper_1_1_chunk
_timescaledb_internal._hyper_1_2_chunk
(2 rows)
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from plain table to hypertable during hypertable creation with RESTRICT
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 0:00:00', 'd1', 1.0);
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 1:00:00', 'd1', 1.0);
CREATE TABLE event(time timestamptz references metrics(time) ON DELETE RESTRICT ON UPDATE RESTRICT, info text);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2020-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
\set ON_ERROR_STOP 0
-- should fail
UPDATE event SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
BEGIN;
UPDATE event SET time = '2020-01-01 01:00:00' WHERE time = '2020-01-01';
ROLLBACK;
\set ON_ERROR_STOP 0
-- should fail
DELETE FROM metrics WHERE time = '2020-01-01';
ERROR: update or delete on table "_hyper_2_3_chunk" violates foreign key constraint "event_time_fkey1" on table "event"
-- should fail
UPDATE metrics SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: update or delete on table "_hyper_2_3_chunk" violates foreign key constraint "event_time_fkey1" on table "event"
\set ON_ERROR_STOP 1
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_2_3_chunk | t
(2 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
------------------------+--------+--------------+---------------
"RI_FKey_restrict_del" | f | t | event
"RI_FKey_restrict_upd" | f | t | event
"RI_FKey_restrict_del" | t | t | event
"RI_FKey_restrict_upd" | t | t | event
(4 rows)
-- create new chunk and repeat the test
INSERT INTO metrics(time, device, value) VALUES ('2021-01-01', 'd1', 1.0);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2021-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2021-01-01', 'info2');
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_2_3_chunk | t
event_time_fkey2 | event | _timescaledb_internal._hyper_2_4_chunk | t
(3 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
------------------------+--------+--------------+---------------
"RI_FKey_restrict_del" | f | t | event
"RI_FKey_restrict_upd" | f | t | event
"RI_FKey_restrict_del" | t | t | event
"RI_FKey_restrict_upd" | t | t | event
"RI_FKey_restrict_del" | t | t | event
"RI_FKey_restrict_upd" | t | t | event
(6 rows)
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from plain table to hypertable during hypertable creation with CASCADE
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 0:00:00', 'd1', 1.0);
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 1:00:00', 'd1', 1.0);
CREATE TABLE event(time timestamptz references metrics(time) ON DELETE CASCADE ON UPDATE CASCADE, info text);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2020-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
\set ON_ERROR_STOP 0
-- should fail
UPDATE event SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
BEGIN;
UPDATE event SET time = '2020-01-01 01:00:00' WHERE time = '2020-01-01';
ROLLBACK;
-- should cascade
BEGIN;
DELETE FROM metrics WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------+------
(0 rows)
ROLLBACK;
-- should cascade
BEGIN;
UPDATE metrics SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------------------------------+-------
Wed Jan 01 00:30:00 2020 PST | info2
(1 row)
ROLLBACK;
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_3_5_chunk | t
(2 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
-----------------------+--------+--------------+---------------
"RI_FKey_cascade_del" | f | t | event
"RI_FKey_cascade_upd" | f | t | event
"RI_FKey_cascade_del" | t | t | event
"RI_FKey_cascade_upd" | t | t | event
(4 rows)
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from plain table to hypertable during hypertable creation with SET NULL
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 0:00:00', 'd1', 1.0);
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 1:00:00', 'd1', 1.0);
CREATE TABLE event(time timestamptz references metrics(time) ON DELETE SET NULL ON UPDATE SET NULL, info text);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2020-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
\set ON_ERROR_STOP 0
-- should fail
UPDATE event SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
BEGIN;
UPDATE event SET time = '2020-01-01 01:00:00' WHERE time = '2020-01-01';
ROLLBACK;
-- should cascade
BEGIN;
DELETE FROM metrics WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------+-------
| info2
(1 row)
ROLLBACK;
-- should cascade
BEGIN;
UPDATE metrics SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------+-------
| info2
(1 row)
ROLLBACK;
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_4_6_chunk | t
(2 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
-----------------------+--------+--------------+---------------
"RI_FKey_setnull_del" | f | t | event
"RI_FKey_setnull_upd" | f | t | event
"RI_FKey_setnull_del" | t | t | event
"RI_FKey_setnull_upd" | t | t | event
(4 rows)
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from plain table to hypertable during hypertable creation with SET DEFAULT
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 0:00:00', 'd1', 1.0);
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 1:00:00', 'd1', 1.0);
CREATE TABLE event(time timestamptz default null references metrics(time) ON DELETE SET DEFAULT ON UPDATE SET DEFAULT, info text);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2020-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
\set ON_ERROR_STOP 0
-- should fail
UPDATE event SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
BEGIN;
UPDATE event SET time = '2020-01-01 01:00:00' WHERE time = '2020-01-01';
ROLLBACK;
-- should cascade
BEGIN;
DELETE FROM metrics WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------+-------
| info2
(1 row)
ROLLBACK;
-- should cascade
BEGIN;
UPDATE metrics SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------+-------
| info2
(1 row)
ROLLBACK;
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_5_7_chunk | t
(2 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
--------------------------+--------+--------------+---------------
"RI_FKey_setdefault_del" | f | t | event
"RI_FKey_setdefault_upd" | f | t | event
"RI_FKey_setdefault_del" | t | t | event
"RI_FKey_setdefault_upd" | t | t | event
(4 rows)
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from plain table to hypertable with constraint being added separately
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01', 'd1', 1.0);
CREATE TABLE event(time timestamptz, info text);
ALTER TABLE event ADD CONSTRAINT event_time_fkey FOREIGN KEY (time) REFERENCES metrics(time) ON DELETE RESTRICT;
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2020-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
-- should fail
\set ON_ERROR_STOP 0
DELETE FROM metrics WHERE time = '2020-01-01';
ERROR: update or delete on table "_hyper_6_8_chunk" violates foreign key constraint "event_time_fkey1" on table "event"
\set ON_ERROR_STOP 1
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_6_8_chunk | t
(2 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
------------------------+--------+--------------+---------------
"RI_FKey_restrict_del" | f | t | event
"RI_FKey_noaction_upd" | f | t | event
"RI_FKey_restrict_del" | t | t | event
"RI_FKey_noaction_upd" | t | t | event
(4 rows)
DROP TABLE event;
DROP TABLE metrics;
-- test multi column fk constraint from plain table to hypertable
CREATE TABLE metrics(time timestamptz , device text, value float, primary key (time, device));
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01', 'd1', 1.0);
CREATE TABLE event(time timestamptz, device text, info text);
ALTER TABLE event ADD CONSTRAINT event_time_fkey FOREIGN KEY (time,device) REFERENCES metrics(time,device) ON DELETE RESTRICT;
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, device, info) VALUES ('2020-01-02', 'd1', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
INSERT INTO event(time, device, info) VALUES ('2020-01-01', 'd2', 'info2');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, device, info) VALUES ('2020-01-01', 'd1', 'info2');
-- should fail
\set ON_ERROR_STOP 0
DELETE FROM metrics WHERE time = '2020-01-01';
ERROR: update or delete on table "_hyper_7_9_chunk" violates foreign key constraint "event_time_device_fkey" on table "event"
DELETE FROM metrics WHERE device = 'd1';
ERROR: update or delete on table "_hyper_7_9_chunk" violates foreign key constraint "event_time_device_fkey" on table "event"
\set ON_ERROR_STOP 1
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from plain table to hypertable with constraint being added separately while data is present
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01', 'd1', 1.0);
CREATE TABLE event(time timestamptz, info text);
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
INSERT INTO event(time, info) VALUES ('2020-02-01', 'info1');
-- should fail
\set ON_ERROR_STOP 0
ALTER TABLE event ADD CONSTRAINT event_time_fkey FOREIGN KEY (time) REFERENCES metrics(time) ON DELETE SET NULL;
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
INSERT INTO metrics(time, device, value) VALUES ('2020-02-01', 'd1', 1.0);
ALTER TABLE event ADD CONSTRAINT event_time_fkey FOREIGN KEY (time) REFERENCES metrics(time) ON DELETE CASCADE;
-- delete should cascade
DELETE FROM metrics WHERE time = '2020-01-01';
SELECT * FROM event;
time | info
------------------------------+-------
Sat Feb 01 00:00:00 2020 PST | info1
(1 row)
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from plain table to compressed hypertable
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 0:00:00', 'd1', 1.0);
INSERT INTO metrics(time, device, value) VALUES ('2020-01-01 1:00:00', 'd1', 1.0);
ALTER TABLE metrics SET(timescaledb.compress, timescaledb.compress_segmentby='device');
NOTICE: default order by for hypertable "metrics" is set to ""time" DESC"
SELECT count(compress_chunk(ch)) FROM show_chunks('metrics') ch;
count
-------
1
(1 row)
CREATE TABLE event(time timestamptz references metrics(time) ON DELETE CASCADE ON UPDATE CASCADE, info text);
-- should fail
\set ON_ERROR_STOP 0
INSERT INTO event(time, info) VALUES ('2020-01-02', 'info1');
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
INSERT INTO event(time, info) VALUES ('2020-01-01', 'info2');
\set ON_ERROR_STOP 0
-- should fail
UPDATE event SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
ERROR: insert or update on table "event" violates foreign key constraint "event_time_fkey"
\set ON_ERROR_STOP 1
-- should succeed
BEGIN;
UPDATE event SET time = '2020-01-01 01:00:00' WHERE time = '2020-01-01';
ROLLBACK;
-- should cascade
BEGIN;
DELETE FROM metrics WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------+------
(0 rows)
ROLLBACK;
-- should cascade
BEGIN;
UPDATE metrics SET time = '2020-01-01 00:30:00' WHERE time = '2020-01-01';
SELECT * FROM event ORDER BY event;
time | info
------------------------------+-------
Wed Jan 01 00:30:00 2020 PST | info2
(1 row)
ROLLBACK;
SELECT conname, conrelid::regclass, confrelid::regclass, conparentid <> 0 AS parent FROM pg_constraint WHERE conrelid='event'::regclass ORDER BY oid;
conname | conrelid | confrelid | parent
------------------+----------+-----------------------------------------+--------
event_time_fkey | event | metrics | f
event_time_fkey1 | event | _timescaledb_internal._hyper_9_12_chunk | t
(2 rows)
SELECT tgfoid::regproc, tgparentid <> 0 AS parent, tgisinternal, tgconstrrelid::regclass FROM pg_trigger WHERE tgconstrrelid='event'::regclass ORDER BY oid;
tgfoid | parent | tgisinternal | tgconstrrelid
-----------------------+--------+--------------+---------------
"RI_FKey_cascade_del" | f | t | event
"RI_FKey_cascade_upd" | f | t | event
"RI_FKey_cascade_del" | t | t | event
"RI_FKey_cascade_upd" | t | t | event
(4 rows)
DROP TABLE event;
DROP TABLE metrics;
-- test single column fk constraint from hypertable to hypertable
CREATE TABLE metrics(time timestamptz primary key, device text, value float);
SELECT table_name FROM create_hypertable('metrics', 'time');
table_name
------------
metrics
(1 row)
CREATE TABLE event(time timestamptz, info text);
SELECT table_name FROM create_hypertable('event', 'time');
NOTICE: adding not-null constraint to column "time"
table_name
------------
event
(1 row)
\set ON_ERROR_STOP 0
ALTER TABLE event ADD CONSTRAINT event_time_fkey FOREIGN KEY (time) REFERENCES metrics(time);
ERROR: hypertables cannot be used as foreign key references of hypertables
\set ON_ERROR_STOP 1
CREATE TABLE event2(time timestamptz REFERENCES metrics(time), info text);
\set ON_ERROR_STOP 0
SELECT table_name FROM create_hypertable('event2', 'time');
ERROR: hypertables cannot be used as foreign key references of hypertables
\set ON_ERROR_STOP 1
DROP TABLE event;
DROP TABLE event2;
DROP TABLE metrics;
-- test FK behavior with different cascading configurations
CREATE TABLE fk_no_action(fk_no_action text primary key);
CREATE TABLE fk_restrict(fk_restrict text primary key);
CREATE TABLE fk_cascade(fk_cascade text primary key);
CREATE TABLE fk_set_null(fk_set_null text primary key);
CREATE TABLE fk_set_default(fk_set_default text primary key);
CREATE TABLE ht(
time timestamptz not null,
fk_no_action text references fk_no_action(fk_no_action) ON DELETE NO ACTION ON UPDATE NO ACTION,
fk_restrict text references fk_restrict(fk_restrict) ON DELETE RESTRICT ON UPDATE RESTRICT,
fk_cascade text references fk_cascade(fk_cascade) ON DELETE CASCADE ON UPDATE CASCADE,
fk_set_null text references fk_set_null(fk_set_null) ON DELETE SET NULL ON UPDATE SET NULL,
fk_set_default text default 'default' references fk_set_default(fk_set_default) ON DELETE SET DEFAULT ON UPDATE SET DEFAULT
);
SELECT table_name FROM create_hypertable('ht', 'time');
table_name
------------
ht
(1 row)
ALTER TABLE ht SET(timescaledb.compress, timescaledb.compress_segmentby='fk_no_action,fk_restrict,fk_cascade,fk_set_null,fk_set_default');
NOTICE: default order by for hypertable "ht" is set to ""time" DESC"
\set ON_ERROR_STOP 0
INSERT INTO fk_set_default(fk_set_default) VALUES ('default');
INSERT INTO ht(time) VALUES ('2020-01-01');
-- NO ACTION
-- should fail with foreign key violation
INSERT INTO ht(time, fk_no_action) VALUES ('2020-01-01', 'fk_no_action');
ERROR: insert or update on table "_hyper_13_14_chunk" violates foreign key constraint "14_14_ht_fk_no_action_fkey"
-- ON UPDATE NO ACTION
BEGIN;
INSERT INTO fk_no_action(fk_no_action) VALUES ('fk_no_action');
INSERT INTO ht(time, fk_no_action) VALUES ('2020-01-01', 'fk_no_action');
-- should error
UPDATE fk_no_action SET fk_no_action = 'fk_no_action_updated';
ERROR: update or delete on table "fk_no_action" violates foreign key constraint "ht_fk_no_action_fkey" on table "ht"
ROLLBACK;
-- ON UPDATE NO ACTION with compression
BEGIN;
INSERT INTO fk_no_action(fk_no_action) VALUES ('fk_no_action');
INSERT INTO ht(time, fk_no_action) VALUES ('2020-01-01', 'fk_no_action');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should error
UPDATE fk_no_action SET fk_no_action = 'fk_no_action_updated';
ERROR: update or delete on table "fk_no_action" violates foreign key constraint "ht_fk_no_action_fkey" on table "ht"
ROLLBACK;
-- ON DELETE NO ACTION
BEGIN;
INSERT INTO fk_no_action(fk_no_action) VALUES ('fk_no_action');
INSERT INTO ht(time, fk_no_action) VALUES ('2020-01-01', 'fk_no_action');
-- should error
DELETE FROM fk_no_action;
ERROR: update or delete on table "fk_no_action" violates foreign key constraint "ht_fk_no_action_fkey" on table "ht"
ROLLBACK;
-- ON DELETE NO ACTION with compression
BEGIN;
INSERT INTO fk_no_action(fk_no_action) VALUES ('fk_no_action');
INSERT INTO ht(time, fk_no_action) VALUES ('2020-01-01', 'fk_no_action');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should error
DELETE FROM fk_no_action;
ERROR: update or delete on table "fk_no_action" violates foreign key constraint "ht_fk_no_action_fkey" on table "ht"
ROLLBACK;
-- RESTRICT
-- should fail with foreign key violation
INSERT INTO ht(time, fk_restrict) VALUES ('2020-01-01', 'fk_restrict');
ERROR: insert or update on table "_hyper_13_14_chunk" violates foreign key constraint "14_15_ht_fk_restrict_fkey"
-- ON UPDATE RESTRICT
BEGIN;
INSERT INTO fk_restrict(fk_restrict) VALUES ('fk_restrict');
INSERT INTO ht(time, fk_restrict) VALUES ('2020-01-01', 'fk_restrict');
-- should error
UPDATE fk_restrict SET fk_restrict = 'fk_restrict_updated';
ERROR: update or delete on table "fk_restrict" violates foreign key constraint "ht_fk_restrict_fkey" on table "ht"
ROLLBACK;
-- ON UPDATE RESTRICT with compression
BEGIN;
INSERT INTO fk_restrict(fk_restrict) VALUES ('fk_restrict');
INSERT INTO ht(time, fk_restrict) VALUES ('2020-01-01', 'fk_restrict');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should error
UPDATE fk_restrict SET fk_restrict = 'fk_restrict_updated';
ERROR: update or delete on table "fk_restrict" violates foreign key constraint "ht_fk_restrict_fkey" on table "ht"
ROLLBACK;
-- ON DELETE RESTRICT
BEGIN;
INSERT INTO fk_restrict(fk_restrict) VALUES ('fk_restrict');
INSERT INTO ht(time, fk_restrict) VALUES ('2020-01-01', 'fk_restrict');
-- should error
DELETE FROM fk_restrict;
ERROR: update or delete on table "fk_restrict" violates foreign key constraint "ht_fk_restrict_fkey" on table "ht"
ROLLBACK;
-- ON DELETE RESTRICT with compression
BEGIN;
INSERT INTO fk_restrict(fk_restrict) VALUES ('fk_restrict');
INSERT INTO ht(time, fk_restrict) VALUES ('2020-01-01', 'fk_restrict');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should error
DELETE FROM fk_restrict;
ERROR: update or delete on table "fk_restrict" violates foreign key constraint "ht_fk_restrict_fkey" on table "ht"
ROLLBACK;
-- CASCADE
-- should fail with foreign key violation
INSERT INTO ht(time, fk_cascade) VALUES ('2020-01-01', 'fk_cascade');
ERROR: insert or update on table "_hyper_13_14_chunk" violates foreign key constraint "14_13_ht_fk_cascade_fkey"
-- ON UPDATE CASCADE
BEGIN;
INSERT INTO fk_cascade(fk_cascade) VALUES ('fk_cascade');
INSERT INTO ht(time, fk_cascade) VALUES ('2020-01-01', 'fk_cascade');
-- should cascade
UPDATE fk_cascade SET fk_cascade = 'fk_cascade_updated';
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+--------------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | fk_cascade_updated | | default
(2 rows)
ROLLBACK;
-- ON UPDATE CASCADE with compression
BEGIN;
INSERT INTO fk_cascade(fk_cascade) VALUES ('fk_cascade');
INSERT INTO ht(time, fk_cascade) VALUES ('2020-01-01', 'fk_cascade');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should cascade
UPDATE fk_cascade SET fk_cascade = 'fk_cascade_updated';
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+--------------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | fk_cascade_updated | | default
(2 rows)
EXPLAIN (analyze, costs off, timing off, summary off) SELECT * FROM ht;
QUERY PLAN
-----------------------------------------------------------------------------------
Append (actual rows=2 loops=1)
-> Custom Scan (DecompressChunk) on _hyper_13_14_chunk (actual rows=1 loops=1)
-> Seq Scan on compress_hyper_14_19_chunk (actual rows=1 loops=1)
-> Seq Scan on _hyper_13_14_chunk (actual rows=1 loops=1)
(4 rows)
ROLLBACK;
-- ON DELETE CASCADE
BEGIN;
INSERT INTO fk_cascade(fk_cascade) VALUES ('fk_cascade');
INSERT INTO ht(time, fk_cascade) VALUES ('2020-01-01', 'fk_cascade');
-- should cascade
DELETE FROM fk_cascade;
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
(1 row)
ROLLBACK;
-- ON DELETE CASCADE with compression without direct batch delete
SET timescaledb.enable_compressed_direct_batch_delete TO false;
BEGIN;
INSERT INTO fk_cascade(fk_cascade) VALUES ('fk_cascade');
INSERT INTO ht(time, fk_cascade) VALUES ('2020-01-01', 'fk_cascade');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should cascade
DELETE FROM fk_cascade;
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
(1 row)
EXPLAIN (analyze, costs off, timing off, summary off) SELECT * FROM ht;
QUERY PLAN
-----------------------------------------------------------------------------------
Append (actual rows=1 loops=1)
-> Custom Scan (DecompressChunk) on _hyper_13_14_chunk (actual rows=1 loops=1)
-> Seq Scan on compress_hyper_14_20_chunk (actual rows=1 loops=1)
-> Seq Scan on _hyper_13_14_chunk (actual rows=0 loops=1)
(4 rows)
ROLLBACK;
RESET timescaledb.enable_compressed_direct_batch_delete;
-- ON DELETE CASCADE with compression and direct batch delete
BEGIN;
INSERT INTO fk_cascade(fk_cascade) VALUES ('fk_cascade');
INSERT INTO ht(time, fk_cascade) VALUES ('2020-01-01', 'fk_cascade');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should cascade
DELETE FROM fk_cascade;
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
(1 row)
EXPLAIN (analyze, costs off, timing off, summary off) SELECT * FROM ht;
QUERY PLAN
-----------------------------------------------------------------------------
Custom Scan (DecompressChunk) on _hyper_13_14_chunk (actual rows=1 loops=1)
-> Seq Scan on compress_hyper_14_21_chunk (actual rows=1 loops=1)
(2 rows)
ROLLBACK;
-- SET NULL
-- should fail with foreign key violation
INSERT INTO ht(time, fk_set_null) VALUES ('2020-01-01', 'fk_set_null');
ERROR: insert or update on table "_hyper_13_14_chunk" violates foreign key constraint "14_17_ht_fk_set_null_fkey"
-- ON UPDATE SET NULL
BEGIN;
INSERT INTO fk_set_null(fk_set_null) VALUES ('fk_set_null');
INSERT INTO ht(time, fk_set_null) VALUES ('2020-01-01', 'fk_set_null');
-- should set column to null
UPDATE fk_set_null SET fk_set_null = 'fk_set_null_updated';
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | default
(2 rows)
ROLLBACK;
-- ON UPDATE SET NULL with compression
BEGIN;
INSERT INTO fk_set_null(fk_set_null) VALUES ('fk_set_null');
INSERT INTO ht(time, fk_set_null) VALUES ('2020-01-01', 'fk_set_null');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should set column to null
UPDATE fk_set_null SET fk_set_null = 'fk_set_null_updated';
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | default
(2 rows)
EXPLAIN (analyze, costs off, timing off, summary off) SELECT * FROM ht;
QUERY PLAN
-----------------------------------------------------------------------------------
Append (actual rows=2 loops=1)
-> Custom Scan (DecompressChunk) on _hyper_13_14_chunk (actual rows=1 loops=1)
-> Seq Scan on compress_hyper_14_22_chunk (actual rows=1 loops=1)
-> Seq Scan on _hyper_13_14_chunk (actual rows=1 loops=1)
(4 rows)
ROLLBACK;
-- ON DELETE SET NULL
BEGIN;
INSERT INTO fk_set_null(fk_set_null) VALUES ('fk_set_null');
INSERT INTO ht(time, fk_set_null) VALUES ('2020-01-01', 'fk_set_null');
-- should set column to null
DELETE FROM fk_set_null;
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | default
(2 rows)
ROLLBACK;
-- ON DELETE SET NULL with compression
BEGIN;
INSERT INTO fk_set_null(fk_set_null) VALUES ('fk_set_null');
INSERT INTO ht(time, fk_set_null) VALUES ('2020-01-01', 'fk_set_null');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
-- should set column to null
DELETE FROM fk_set_null;
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | default
(2 rows)
EXPLAIN (analyze, costs off, timing off, summary off) SELECT * FROM ht;
QUERY PLAN
-----------------------------------------------------------------------------------
Append (actual rows=2 loops=1)
-> Custom Scan (DecompressChunk) on _hyper_13_14_chunk (actual rows=1 loops=1)
-> Seq Scan on compress_hyper_14_23_chunk (actual rows=1 loops=1)
-> Seq Scan on _hyper_13_14_chunk (actual rows=1 loops=1)
(4 rows)
ROLLBACK;
-- SET DEFAULT
-- should fail with foreign key violation
INSERT INTO ht(time, fk_set_default) VALUES ('2020-01-01', 'fk_set_default');
ERROR: insert or update on table "_hyper_13_14_chunk" violates foreign key constraint "14_16_ht_fk_set_default_fkey"
-- ON UPDATE SET DEFAULT
BEGIN;
INSERT INTO fk_set_default(fk_set_default) VALUES ('fk_set_default');
INSERT INTO ht(time, fk_set_default) VALUES ('2020-01-01', 'fk_set_default');
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | fk_set_default
(2 rows)
UPDATE fk_set_default SET fk_set_default = 'fk_set_default_updated' WHERE fk_set_default = 'fk_set_default';
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | default
(2 rows)
ROLLBACK;
-- ON UPDATE SET DEFAULT with compression
BEGIN;
INSERT INTO fk_set_default(fk_set_default) VALUES ('fk_set_default');
INSERT INTO ht(time, fk_set_default) VALUES ('2020-01-01', 'fk_set_default');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | fk_set_default
(2 rows)
UPDATE fk_set_default SET fk_set_default = 'fk_set_default_updated' WHERE fk_set_default = 'fk_set_default';
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | default
(2 rows)
EXPLAIN (analyze, costs off, timing off, summary off) SELECT * FROM ht;
QUERY PLAN
-----------------------------------------------------------------------------------
Append (actual rows=2 loops=1)
-> Custom Scan (DecompressChunk) on _hyper_13_14_chunk (actual rows=1 loops=1)
-> Seq Scan on compress_hyper_14_24_chunk (actual rows=1 loops=1)
-> Seq Scan on _hyper_13_14_chunk (actual rows=1 loops=1)
(4 rows)
ROLLBACK;
-- ON DELETE SET DEFAULT
BEGIN;
INSERT INTO fk_set_default(fk_set_default) VALUES ('fk_set_default');
INSERT INTO ht(time, fk_set_default) VALUES ('2020-01-01', 'fk_set_default');
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | fk_set_default
(2 rows)
DELETE FROM fk_set_default WHERE fk_set_default = 'fk_set_default';
ROLLBACK;
-- ON DELETE SET DEFAULT with compression
BEGIN;
INSERT INTO fk_set_default(fk_set_default) VALUES ('fk_set_default');
INSERT INTO ht(time, fk_set_default) VALUES ('2020-01-01', 'fk_set_default');
SELECT count(compress_chunk(ch)) FROM show_chunks('ht') ch;
count
-------
1
(1 row)
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | fk_set_default
(2 rows)
DELETE FROM fk_set_default WHERE fk_set_default = 'fk_set_default';
SELECT * FROM ht;
time | fk_no_action | fk_restrict | fk_cascade | fk_set_null | fk_set_default
------------------------------+--------------+-------------+------------+-------------+----------------
Wed Jan 01 00:00:00 2020 PST | | | | | default
Wed Jan 01 00:00:00 2020 PST | | | | | default
(2 rows)
EXPLAIN (analyze, costs off, timing off, summary off) SELECT * FROM ht;
QUERY PLAN
-----------------------------------------------------------------------------------
Append (actual rows=2 loops=1)
-> Custom Scan (DecompressChunk) on _hyper_13_14_chunk (actual rows=1 loops=1)
-> Seq Scan on compress_hyper_14_25_chunk (actual rows=1 loops=1)
-> Seq Scan on _hyper_13_14_chunk (actual rows=1 loops=1)
(4 rows)
ROLLBACK;
-- #7226
-- test multi-column fk constraint where constraint column order is different from index column order
CREATE TABLE i7226(time timestamptz, device_id int, PRIMARY KEY (device_id, time));
SELECT create_hypertable('i7226', 'time');
create_hypertable
---------------------
(15,public,i7226,t)
(1 row)
CREATE TABLE i7226_valid(time timestamptz NOT NULL,device_id int NOT NULL, FOREIGN KEY(time, device_id) REFERENCES i7226(time, device_id));
INSERT INTO i7226 VALUES ('2024-08-29 12:00:00+00', 1);
-- test foreign key constraints that have been created before hypertable conversion
create table converted_pk(time timestamptz, id int, unique(time, id));
create table converted_fk(time timestamptz, id int, foreign key (time, id) references converted_pk(time, id));
select table_name FROM create_hypertable ('converted_pk', 'time');
NOTICE: adding not-null constraint to column "time"
table_name
--------------
converted_pk
(1 row)
\set ON_ERROR_STOP 0
-- should fail
INSERT INTO converted_fk SELECT '2020-01-01', 1;
ERROR: insert or update on table "converted_fk" violates foreign key constraint "converted_fk_time_id_fkey"
\set ON_ERROR_STOP 1
INSERT INTO converted_pk SELECT '2020-01-01 0:01', 1;
\set ON_ERROR_STOP 0
-- should still fail
INSERT INTO converted_fk SELECT '2020-01-01', 1;
ERROR: insert or update on table "converted_fk" violates foreign key constraint "converted_fk_time_id_fkey"
\set ON_ERROR_STOP 1
INSERT INTO converted_fk SELECT '2020-01-01 0:01', 1;
\set ON_ERROR_STOP 0
-- should fail
DELETE FROM converted_pk WHERE time = '2020-01-01 0:01';
ERROR: update or delete on table "_hyper_16_27_chunk" violates foreign key constraint "converted_fk_time_id_fkey1" on table "converted_fk"
TRUNCATE converted_pk;
ERROR: cannot truncate a table referenced in a foreign key constraint
\set ON_ERROR_STOP 1
DELETE FROM converted_fk;
DELETE FROM converted_pk WHERE time = '2020-01-01 0:01';