mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-14 17:43:34 +08:00
Rename columns in old-style continuous aggregates
For continuous aggregates with the old-style partial aggregates renaming columns that are not in the group-by clause will generate an error when upgrading to a later version. The reason is that it is implicitly assumed that the name of the column is the same as for the direct view. This holds true for new-style continous aggregates, but is not always true for old-style continuous aggregates. In particular, columns that are not part of the `GROUP BY` clause can have an internally generated name. This commit fixes that by extracting the name of the column from the partial view and use that when renaming the partial view column and the materialized table column.
This commit is contained in:
parent
e2e7ae3045
commit
a6ff7ba6cc
@ -11,9 +11,12 @@ accidentally triggering the load of a previous DB version.**
|
||||
* #5362 Make copy fetcher more async
|
||||
* #5336 Use NameData and namestrcpy for names
|
||||
* #5317 Fix some incorrect memory handling
|
||||
* #5367 Rename columns in old-style continuous aggregates
|
||||
|
||||
**Thanks**
|
||||
* @Medvecrab for discovering an issue with copying NameData when forming heap tuples.
|
||||
* @pushpeepkmonroe for discovering an issue in upgrading old-style
|
||||
continuous aggregates with renamed columns
|
||||
|
||||
## 2.10.0 (2023-02-21)
|
||||
|
||||
|
@ -6,10 +6,11 @@ DROP FUNCTION IF EXISTS _timescaledb_internal.time_col_type_for_chunk(name,name)
|
||||
-- in a table.
|
||||
CREATE TABLE _timescaledb_internal.rename_tables (
|
||||
user_view regclass,
|
||||
new_name text,
|
||||
old_name text,
|
||||
user_column text,
|
||||
partial_view regclass,
|
||||
partial_column text,
|
||||
direct_view regclass,
|
||||
direct_column text,
|
||||
mat_table regclass,
|
||||
hypertable_id int
|
||||
);
|
||||
@ -31,24 +32,32 @@ WITH
|
||||
SELECT attrelid, attname, attnum, mat_id
|
||||
FROM objs, pg_attribute
|
||||
WHERE attrelid = objs.user_view),
|
||||
partial_view AS (
|
||||
SELECT attrelid, attname, attnum, mat_id
|
||||
FROM objs, pg_attribute
|
||||
WHERE attrelid = objs.partial_view),
|
||||
direct_view AS (
|
||||
SELECT attrelid, attname, attnum, mat_id
|
||||
FROM objs, pg_attribute
|
||||
WHERE attrelid = objs.direct_view)
|
||||
INSERT INTO _timescaledb_internal.rename_tables
|
||||
SELECT (SELECT user_view FROM objs WHERE uv.attrelid = user_view),
|
||||
uv.attname AS new_name,
|
||||
dv.attname AS old_name,
|
||||
uv.attname AS user_column,
|
||||
(SELECT partial_view FROM objs WHERE uv.attrelid = user_view),
|
||||
pv.attname AS partial_column,
|
||||
(SELECT direct_view FROM objs WHERE uv.attrelid = user_view),
|
||||
dv.attname AS direct_column,
|
||||
(SELECT mat_table FROM objs WHERE uv.attrelid = user_view),
|
||||
(SELECT mat_id FROM objs WHERE uv.attrelid = user_view)
|
||||
FROM user_view uv JOIN direct_view dv USING (mat_id, attnum)
|
||||
JOIN partial_view pv USING (mat_id, attnum)
|
||||
WHERE uv.attname != dv.attname;
|
||||
|
||||
CREATE PROCEDURE _timescaledb_internal.alter_table_column(cagg regclass, relation regclass, old_column_name name, new_column_name name) AS $$
|
||||
BEGIN
|
||||
EXECUTE format('ALTER TABLE %s RENAME COLUMN %I TO %I', relation, old_column_name, new_column_name);
|
||||
IF old_column_name != new_column_name THEN
|
||||
EXECUTE format('ALTER TABLE %s RENAME COLUMN %I TO %I', relation, old_column_name, new_column_name);
|
||||
END IF;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
@ -59,23 +68,24 @@ DO
|
||||
$$
|
||||
DECLARE
|
||||
user_view regclass;
|
||||
new_name name;
|
||||
old_name name;
|
||||
user_column name;
|
||||
partial_view regclass;
|
||||
partial_column name;
|
||||
direct_view regclass;
|
||||
direct_column name;
|
||||
mat_table regclass;
|
||||
ht_id int;
|
||||
BEGIN
|
||||
FOR user_view, new_name, old_name, partial_view, direct_view, mat_table, ht_id IN
|
||||
FOR user_view, user_column, partial_view, partial_column, direct_view, direct_column, mat_table, ht_id IN
|
||||
SELECT * FROM _timescaledb_internal.rename_tables
|
||||
LOOP
|
||||
-- There is no RENAME COLUMN for views, but we can use ALTER TABLE
|
||||
-- to rename a column in a view.
|
||||
CALL _timescaledb_internal.alter_table_column(user_view, partial_view, old_name, new_name);
|
||||
CALL _timescaledb_internal.alter_table_column(user_view, direct_view, old_name, new_name);
|
||||
CALL _timescaledb_internal.alter_table_column(user_view, mat_table, old_name, new_name);
|
||||
UPDATE _timescaledb_catalog.dimension SET column_name = new_name
|
||||
WHERE hypertable_id = ht_id AND column_name = old_name;
|
||||
CALL _timescaledb_internal.alter_table_column(user_view, partial_view, partial_column, user_column);
|
||||
CALL _timescaledb_internal.alter_table_column(user_view, direct_view, direct_column, user_column);
|
||||
CALL _timescaledb_internal.alter_table_column(user_view, mat_table, partial_column, user_column);
|
||||
UPDATE _timescaledb_catalog.dimension SET column_name = user_column
|
||||
WHERE hypertable_id = ht_id AND column_name = direct_column;
|
||||
END LOOP;
|
||||
END
|
||||
$$;
|
||||
|
@ -21,7 +21,8 @@ SELECT
|
||||
:ts_major >= 2 AS has_create_mat_view,
|
||||
:ts_major >= 2 AS has_continuous_aggs_policy,
|
||||
:ts_major = 2 AND :ts_minor >= 7 AS has_continuous_aggs_finals_form,
|
||||
:ts_major = 2 AND :ts_minor IN (7,8) AS has_continuous_aggs_finalized_option
|
||||
:ts_major = 2 AND :ts_minor IN (7,8) AS has_continuous_aggs_finalized_option,
|
||||
:ts_major = 2 AND :ts_minor IN (5) AS has_cagg_rename_col_bug
|
||||
FROM pg_extension
|
||||
WHERE extname = 'timescaledb' \gset
|
||||
|
||||
@ -69,7 +70,9 @@ SELECT generate_series('2018-11-01 00:00'::timestamp, '2018-12-15 00:00'::timest
|
||||
WITH (timescaledb.continuous, timescaledb.materialized_only=false) AS
|
||||
\endif
|
||||
\endif
|
||||
SELECT time_bucket('1 week', timec) AS bucket, location, round(avg(humidity)) AS humidity
|
||||
SELECT time_bucket('1 week', timec) AS bucket,
|
||||
location,
|
||||
round(avg(humidity)) AS humidity
|
||||
FROM conditions_before
|
||||
\if :has_refresh_mat_view
|
||||
GROUP BY bucket, location;
|
||||
@ -132,15 +135,27 @@ SELECT generate_series('2018-11-01 00:00'::timestamp, '2018-12-15 00:00'::timest
|
||||
\if :has_refresh_mat_view
|
||||
GROUP BY bucket, location
|
||||
HAVING min(location) >= 'NYC' and avg(temperature) > 2;
|
||||
|
||||
-- ALTER VIEW cannot rename columns before PG13, but ALTER TABLE
|
||||
-- works for views.
|
||||
ALTER TABLE rename_cols RENAME COLUMN bucket to "time";
|
||||
--
|
||||
-- Renaming one column that is used in the group by and one that is
|
||||
-- not in the group by. Both should work.
|
||||
ALTER TABLE rename_cols RENAME COLUMN bucket TO "time";
|
||||
\if :has_cagg_rename_col_bug == false
|
||||
ALTER TABLE rename_cols RENAME COLUMN humidity TO moisture;
|
||||
\endif
|
||||
\else
|
||||
GROUP BY bucket, location
|
||||
HAVING min(location) >= 'NYC' and avg(temperature) > 2 WITH NO DATA;
|
||||
SELECT add_continuous_aggregate_policy('mat_before', NULL, '-30 days'::interval, '336 h');
|
||||
|
||||
ALTER MATERIALIZED VIEW rename_cols RENAME COLUMN bucket to "time";
|
||||
-- Renaming one column that is used in the group by and one that
|
||||
-- is not in the group by. Both should work.
|
||||
ALTER MATERIALIZED VIEW rename_cols RENAME COLUMN bucket TO "time";
|
||||
\if :has_cagg_rename_col_bug == false
|
||||
ALTER MATERIALIZED VIEW rename_cols RENAME COLUMN humidity TO moisture;
|
||||
\endif
|
||||
\endif
|
||||
|
||||
\if :WITH_SUPERUSER
|
||||
|
Loading…
x
Reference in New Issue
Block a user