Skip to content

Commit 52443a4

Browse files
committed
Fix hypertable foreign keys for 2.15.X
1 parent 162333d commit 52443a4

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
-- Fix compressed hypertables with FOREIGN KEY constraints that were created with TimescaleDB versions before 2.15.0
2+
CREATE OR REPLACE FUNCTION pg_temp.constraint_columns(regclass, int2[]) RETURNS text[] AS
3+
$$
4+
SELECT array_agg(attname) FROM unnest($2) un(attnum) LEFT JOIN pg_attribute att ON att.attrelid=$1 AND att.attnum = un.attnum;
5+
$$ LANGUAGE SQL SET search_path TO pg_catalog, pg_temp;
6+
7+
DO $$
8+
DECLARE
9+
ht_id int;
10+
ht regclass;
11+
chunk regclass;
12+
con_oid oid;
13+
con_frelid regclass;
14+
con_name text;
15+
con_columns text[];
16+
chunk_id int;
17+
18+
BEGIN
19+
20+
-- iterate over all hypertables that have foreign key constraints
21+
FOR ht_id, ht in
22+
SELECT
23+
ht.id,
24+
format('%I.%I',ht.schema_name,ht.table_name)::regclass
25+
FROM _timescaledb_catalog.hypertable ht
26+
WHERE
27+
EXISTS (
28+
SELECT FROM pg_constraint con
29+
WHERE
30+
con.contype='f' AND
31+
con.conrelid=format('%I.%I',ht.schema_name,ht.table_name)::regclass
32+
)
33+
LOOP
34+
RAISE NOTICE 'Hypertable % has foreign key constraint', ht;
35+
36+
-- iterate over all foreign key constraints on the hypertable
37+
-- and check that they are present on every chunk
38+
FOR con_oid, con_frelid, con_name, con_columns IN
39+
SELECT con.oid, con.confrelid, con.conname, pg_temp.constraint_columns(con.conrelid,con.conkey)
40+
FROM pg_constraint con
41+
WHERE
42+
con.contype='f' AND
43+
con.conrelid=ht
44+
LOOP
45+
RAISE NOTICE 'Checking constraint % %', con_name, con_columns;
46+
-- check that the foreign key constraint is present on the chunk
47+
48+
FOR chunk_id, chunk IN
49+
SELECT
50+
ch.id,
51+
format('%I.%I',ch.schema_name,ch.table_name)::regclass
52+
FROM _timescaledb_catalog.chunk ch
53+
WHERE
54+
ch.hypertable_id=ht_id
55+
LOOP
56+
RAISE NOTICE 'Checking chunk %', chunk;
57+
IF NOT EXISTS (
58+
SELECT FROM pg_constraint con
59+
WHERE
60+
con.contype='f' AND
61+
con.conrelid=chunk AND
62+
con.confrelid=con_frelid AND
63+
pg_temp.constraint_columns(con.conrelid,con.conkey) = con_columns
64+
) THEN
65+
RAISE WARNING 'Restoring constraint % on chunk %', con_name, chunk;
66+
PERFORM _timescaledb_functions.constraint_clone(con_oid, chunk);
67+
INSERT INTO _timescaledb_catalog.chunk_constraint(chunk_id, dimension_slice_id, constraint_name, hypertable_constraint_name) VALUES (chunk_id, NULL, con_name, con_name);
68+
END IF;
69+
70+
END LOOP;
71+
END LOOP;
72+
73+
END LOOP;
74+
75+
END
76+
$$;
77+
78+
DROP FUNCTION pg_temp.constraint_columns(regclass, int2[]);

0 commit comments

Comments
 (0)