22DROP VIEW IF EXISTS _timescaledb_catalog .chunk_constraint ;
33DROP FUNCTION IF EXISTS _timescaledb_functions .chunk_constraint_add_table_constraint ( integer , name, name);
44
5+ ALTER TABLE _timescaledb_catalog .hypertable RESET (user_catalog_table);
6+ ALTER TABLE _timescaledb_catalog .chunk RESET (user_catalog_table);
7+
8+ --
9+ -- Rebuild the catalog table `_timescaledb_catalog.dimension_slice` back to
10+ -- the pre-chunk_id schema. Per-chunk slice duplicates are collapsed back
11+ -- into one shared row per (dimension_id, range_start, range_end), and the
12+ -- old UNIQUE on that triple is restored.
13+ --
14+ CREATE TABLE _timescaledb_internal .tmp_dimension_slice AS
15+ SELECT * FROM _timescaledb_catalog .dimension_slice ;
16+ CREATE TABLE _timescaledb_internal .tmp_dimension_slice_seq_value AS
17+ SELECT last_value, is_called FROM _timescaledb_catalog .dimension_slice_id_seq ;
18+
19+ ALTER EXTENSION timescaledb DROP TABLE _timescaledb_catalog .dimension_slice;
20+ ALTER EXTENSION timescaledb DROP SEQUENCE _timescaledb_catalog .dimension_slice_id_seq ;
21+
22+ DROP TABLE _timescaledb_catalog .dimension_slice ;
23+
24+ CREATE TABLE _timescaledb_catalog .dimension_slice (
25+ id serial NOT NULL ,
26+ dimension_id integer NOT NULL ,
27+ range_start bigint NOT NULL ,
28+ range_end bigint NOT NULL ,
29+ CONSTRAINT dimension_slice_pkey PRIMARY KEY (id),
30+ CONSTRAINT dimension_slice_dimension_id_range_start_range_end_key UNIQUE (dimension_id, range_start, range_end),
31+ CONSTRAINT dimension_slice_check CHECK (range_start <= range_end),
32+ CONSTRAINT dimension_slice_dimension_id_fkey FOREIGN KEY (dimension_id) REFERENCES _timescaledb_catalog .dimension (id) ON DELETE CASCADE
33+ );
34+
35+ -- One row per unique (dimension_id, range_start, range_end), reusing the
36+ -- lowest old id so the chunk-side CHECK named constraint_<min_id> keeps the
37+ -- correct name without renaming.
38+ INSERT INTO _timescaledb_catalog .dimension_slice (id, dimension_id, range_start, range_end)
39+ SELECT min (id), dimension_id, range_start, range_end
40+ FROM _timescaledb_internal .tmp_dimension_slice
41+ GROUP BY dimension_id, range_start, range_end;
42+
43+ -- Rename chunk-side CHECK constraints from constraint_<old_id> to
44+ -- constraint_<kept_id> for chunks whose per-chunk slice was collapsed onto
45+ -- a shared row. Keeps the legacy invariant
46+ -- constraint_name == 'constraint_<dimension_slice_id>'.
47+ DO $$
48+ DECLARE
49+ r RECORD;
50+ BEGIN
51+ FOR r IN
52+ SELECT pg_catalog .format (' %I.%I' , c .schema_name , c .table_name ) AS chunk_table,
53+ format(' constraint_%s' , tmp .id )::name AS old_name,
54+ format(' constraint_%s' , ds .id )::name AS new_name
55+ FROM _timescaledb_internal .tmp_dimension_slice tmp
56+ JOIN _timescaledb_catalog .chunk c ON c .id = tmp .chunk_id
57+ JOIN _timescaledb_catalog .dimension_slice ds
58+ ON ds .dimension_id = tmp .dimension_id
59+ AND ds .range_start = tmp .range_start
60+ AND ds .range_end = tmp .range_end
61+ WHERE tmp .id <> ds .id
62+ AND EXISTS (
63+ SELECT 1 FROM pg_constraint pc
64+ WHERE pc .conrelid = pg_catalog .format (' %I.%I' , c .schema_name , c .table_name )::regclass
65+ AND pc .conname = format(' constraint_%s' , tmp .id )::name
66+ AND pc .contype = ' c'
67+ )
68+ LOOP
69+ EXECUTE pg_catalog .format (' ALTER TABLE %s RENAME CONSTRAINT %I TO %I' ,
70+ r .chunk_table , r .old_name , r .new_name );
71+ END LOOP;
72+ END
73+ $$;
74+
75+ ALTER SEQUENCE _timescaledb_catalog .dimension_slice_id_seq OWNED BY _timescaledb_catalog .dimension_slice .id;
76+ SELECT setval(' _timescaledb_catalog.dimension_slice_id_seq' , last_value, is_called)
77+ FROM _timescaledb_internal .tmp_dimension_slice_seq_value ;
78+
79+ SELECT pg_catalog .pg_extension_config_dump (' _timescaledb_catalog.dimension_slice' , ' ' );
80+ SELECT pg_catalog .pg_extension_config_dump (pg_get_serial_sequence(' _timescaledb_catalog.dimension_slice' , ' id' ), ' ' );
81+
82+ GRANT SELECT ON _timescaledb_catalog .dimension_slice TO PUBLIC;
83+ GRANT SELECT ON _timescaledb_catalog .dimension_slice_id_seq TO PUBLIC;
84+ -- end rebuild _timescaledb_catalog.dimension_slice table --
85+
586-- Recreate the chunk_constraint catalog table.
687CREATE TABLE _timescaledb_catalog .chunk_constraint (
788 chunk_id integer NOT NULL ,
@@ -23,11 +104,17 @@ SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.chunk_constrain
23104GRANT SELECT ON _timescaledb_catalog .chunk_constraint TO PUBLIC;
24105GRANT SELECT ON _timescaledb_catalog .chunk_constraint_name TO PUBLIC;
25106
26- -- Restore the dimensional rows from the per-chunk slice rows.
107+ -- Restore dimensional rows. Join the per-chunk snapshot to the rebuilt
108+ -- (deduplicated) dimension_slice so each chunk_constraint row points
109+ -- directly at the kept slice id.
27110INSERT INTO _timescaledb_catalog .chunk_constraint
28111 (chunk_id, dimension_slice_id, constraint_name, hypertable_constraint_name)
29- SELECT chunk_id, id, format(' constraint_%s' , id)::name, ' ' ::name
30- FROM _timescaledb_catalog .dimension_slice ;
112+ SELECT tmp .chunk_id , ds .id , format(' constraint_%s' , ds .id )::name, ' ' ::name
113+ FROM _timescaledb_internal .tmp_dimension_slice tmp
114+ JOIN _timescaledb_catalog .dimension_slice ds
115+ ON ds .dimension_id = tmp .dimension_id
116+ AND ds .range_start = tmp .range_start
117+ AND ds .range_end = tmp .range_end ;
31118
32119-- Restore chunk_constraint rows for CHECK constraints on OSM chunks.
33120INSERT INTO _timescaledb_catalog .chunk_constraint
@@ -41,11 +128,6 @@ JOIN pg_constraint con
41128WHERE c .osm_chunk
42129ON CONFLICT DO NOTHING;
43130
44- -- Drop chunk stats related objects
45- DROP VIEW IF EXISTS timescaledb_information .stat_chunk_activity ;
46- DROP FUNCTION IF EXISTS _timescaledb_functions .chunk_statistics (regclass, regclass, timestamptz );
47- DROP FUNCTION IF EXISTS _timescaledb_functions .chunk_statistics_reset ();
48-
49131-- Restore chunk_constraint rows for outbound FKs by matching chunk-side
50132-- FKs to their hypertable-side counterpart by name.
51133INSERT INTO _timescaledb_catalog .chunk_constraint
@@ -77,115 +159,24 @@ JOIN pg_constraint child
77159 AND child .conname = format(' %s_%s' , c .id , parent .conname )
78160ON CONFLICT DO NOTHING;
79161
80- ALTER TABLE _timescaledb_catalog .hypertable RESET (user_catalog_table);
81- ALTER TABLE _timescaledb_catalog .chunk RESET (user_catalog_table);
82-
83- --
84- -- Rebuild the catalog table `_timescaledb_catalog.dimension_slice` back to
85- -- the pre-chunk_id schema. Per-chunk slice duplicates are collapsed back
86- -- into one shared row per (dimension_id, range_start, range_end), and the
87- -- old UNIQUE on that triple is restored.
88- --
89- CREATE TABLE _timescaledb_internal .tmp_dimension_slice AS
90- SELECT * FROM _timescaledb_catalog .dimension_slice ;
91- CREATE TABLE _timescaledb_internal .tmp_dimension_slice_seq_value AS
92- SELECT last_value, is_called FROM _timescaledb_catalog .dimension_slice_id_seq ;
93-
94- ALTER EXTENSION timescaledb DROP TABLE _timescaledb_catalog .dimension_slice;
95- ALTER EXTENSION timescaledb DROP SEQUENCE _timescaledb_catalog .dimension_slice_id_seq ;
96-
97- DROP TABLE _timescaledb_catalog .dimension_slice ;
98-
99- CREATE TABLE _timescaledb_catalog .dimension_slice (
100- id serial NOT NULL ,
101- dimension_id integer NOT NULL ,
102- range_start bigint NOT NULL ,
103- range_end bigint NOT NULL ,
104- CONSTRAINT dimension_slice_pkey PRIMARY KEY (id),
105- CONSTRAINT dimension_slice_dimension_id_range_start_range_end_key UNIQUE (dimension_id, range_start, range_end),
106- CONSTRAINT dimension_slice_check CHECK (range_start <= range_end),
107- CONSTRAINT dimension_slice_dimension_id_fkey FOREIGN KEY (dimension_id) REFERENCES _timescaledb_catalog .dimension (id) ON DELETE CASCADE
108- );
109-
110- -- One row per unique (dimension_id, range_start, range_end), reusing the
111- -- lowest old id so existing chunk_constraint rows that already point at
112- -- it don't need repointing.
113- INSERT INTO _timescaledb_catalog .dimension_slice (id, dimension_id, range_start, range_end)
114- SELECT min (id), dimension_id, range_start, range_end
115- FROM _timescaledb_internal .tmp_dimension_slice
116- GROUP BY dimension_id, range_start, range_end;
117-
118- -- Repoint chunk_constraint rows that referenced one of the deduplicated
119- -- (now deleted) slice ids at the kept slice with the same range.
120- UPDATE _timescaledb_catalog .chunk_constraint cc
121- SET dimension_slice_id = ds .id
122- FROM _timescaledb_internal .tmp_dimension_slice tmp,
123- _timescaledb_catalog .dimension_slice ds
124- WHERE cc .dimension_slice_id IS NOT NULL
125- AND tmp .id = cc .dimension_slice_id
126- AND tmp .id <> ds .id
127- AND ds .dimension_id = tmp .dimension_id
128- AND ds .range_start = tmp .range_start
129- AND ds .range_end = tmp .range_end ;
130-
131- -- Restore the legacy invariant constraint_name == 'constraint_<dimension_slice_id>'
132- -- for rows whose dimension_slice_id was just repointed at a deduplicated slice.
133- -- Rename the chunk-side CHECK on disk and update the catalog row in lockstep.
134- DO $$
135- DECLARE
136- r RECORD;
137- BEGIN
138- FOR r IN
139- SELECT pg_catalog .format (' %I.%I' , c .schema_name , c .table_name ) AS chunk_table,
140- cc .constraint_name AS old_name,
141- format(' constraint_%s' , cc .dimension_slice_id )::name AS new_name,
142- cc .chunk_id ,
143- cc .dimension_slice_id
144- FROM _timescaledb_catalog .chunk_constraint cc
145- JOIN _timescaledb_catalog .chunk c ON c .id = cc .chunk_id
146- WHERE cc .dimension_slice_id IS NOT NULL
147- AND cc .constraint_name <> format(' constraint_%s' , cc .dimension_slice_id )::name
148- AND EXISTS (
149- SELECT 1 FROM pg_constraint pc
150- WHERE pc .conrelid = pg_catalog .format (' %I.%I' , c .schema_name , c .table_name )::regclass
151- AND pc .conname = cc .constraint_name
152- AND pc .contype = ' c'
153- )
154- LOOP
155- EXECUTE pg_catalog .format (' ALTER TABLE %s RENAME CONSTRAINT %I TO %I' ,
156- r .chunk_table , r .old_name , r .new_name );
157- UPDATE _timescaledb_catalog .chunk_constraint
158- SET constraint_name = r .new_name
159- WHERE chunk_id = r .chunk_id
160- AND dimension_slice_id = r .dimension_slice_id ;
161- END LOOP;
162- END
163- $$;
164-
165- ALTER SEQUENCE _timescaledb_catalog .dimension_slice_id_seq OWNED BY _timescaledb_catalog .dimension_slice .id;
166- SELECT setval(' _timescaledb_catalog.dimension_slice_id_seq' , last_value, is_called)
167- FROM _timescaledb_internal .tmp_dimension_slice_seq_value ;
168-
169162ALTER TABLE _timescaledb_catalog .chunk_constraint
170163 ADD CONSTRAINT chunk_constraint_dimension_slice_id_fkey
171164 FOREIGN KEY (dimension_slice_id) REFERENCES _timescaledb_catalog .dimension_slice (id);
172165
173166DROP TABLE _timescaledb_internal .tmp_dimension_slice ;
174167DROP TABLE _timescaledb_internal .tmp_dimension_slice_seq_value ;
175168
176- SELECT pg_catalog .pg_extension_config_dump (' _timescaledb_catalog.dimension_slice' , ' ' );
177- SELECT pg_catalog .pg_extension_config_dump (pg_get_serial_sequence(' _timescaledb_catalog.dimension_slice' , ' id' ), ' ' );
178-
179- GRANT SELECT ON _timescaledb_catalog .dimension_slice TO PUBLIC;
180- GRANT SELECT ON _timescaledb_catalog .dimension_slice_id_seq TO PUBLIC;
181- -- end rebuild _timescaledb_catalog.dimension_slice table --
169+ -- Drop chunk stats related objects
170+ DROP VIEW IF EXISTS timescaledb_information .stat_chunk_activity ;
171+ DROP FUNCTION IF EXISTS _timescaledb_functions .chunk_statistics (regclass, regclass, timestamptz );
172+ DROP FUNCTION IF EXISTS _timescaledb_functions .chunk_statistics_reset ();
182173
183174DROP FUNCTION IF EXISTS @extschema@.create_hypertable(relation REGCLASS, time_column_name NAME, partitioning_column NAME, number_partitions INTEGER , associated_schema_name NAME, associated_table_prefix NAME, chunk_time_interval ANYELEMENT, create_default_indexes BOOLEAN , if_not_exists BOOLEAN , partitioning_func REGPROC, migrate_data BOOLEAN , time_partitioning_func REGPROC);
184175
185-
186176-- Restore the chunk_target_size check constraint dropped in the forward path.
187177ALTER TABLE _timescaledb_catalog .hypertable
188178 ADD CONSTRAINT hypertable_chunk_target_size_check CHECK (chunk_target_size >= 0 );
179+
189180DROP FUNCTION IF EXISTS _timescaledb_functions .rebuild_sparse_index (REGCLASS, BOOLEAN );
190181
191182-- Rebuild the catalog table `_timescaledb_catalog.continuous_agg` to drop the
0 commit comments