Skip to content

Commit 7a73b8f

Browse files
committed
Cover seqnum in invalidation log update test
1 parent 4301fce commit 7a73b8f

2 files changed

Lines changed: 72 additions & 31 deletions

File tree

test/sql/updates/post.continuous_aggs.sql

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -105,55 +105,78 @@ END
105105
$$ LANGUAGE PLPGSQL;
106106

107107
-- Dump the invalidation log rows of the inval_log_test fixture so they
108-
-- are part of the baseline/updated/restored comparison.
109-
SELECT h.table_name AS hypertable,
110-
l.lowest_modified_value, l.greatest_modified_value
108+
-- are part of the baseline/updated/restored comparison. The seqnum
109+
-- column only exists from 2.30; this runs on the post-update version,
110+
-- which is the same for all three databases, so the branch taken is
111+
-- identical and the outputs stay comparable.
112+
SELECT EXISTS (
113+
SELECT FROM information_schema.columns
114+
WHERE table_schema = '_timescaledb_catalog'
115+
AND table_name = 'continuous_aggs_hypertable_invalidation_log'
116+
AND column_name = 'seqnum') AS has_inval_log_seqnum \gset
117+
118+
-- Collect the live rows in the same shape as inval_log_snapshot so both
119+
-- the dumps below and the verification compare like with like. This is
120+
-- the only place that has to know whether seqnum exists.
121+
CREATE TEMP VIEW inval_log_live AS
122+
SELECT 'hypertable'::text AS log, h.table_name AS name,
123+
l.lowest_modified_value, l.greatest_modified_value,
124+
\if :has_inval_log_seqnum
125+
l.seqnum
126+
\else
127+
NULL::integer AS seqnum
128+
\endif
111129
FROM _timescaledb_catalog.continuous_aggs_hypertable_invalidation_log l
112130
JOIN _timescaledb_catalog.hypertable h ON h.id = l.hypertable_id
113131
WHERE h.table_name = 'inval_log_test'
114-
ORDER BY 1, 2, 3;
115-
116-
SELECT ca.user_view_name AS cagg,
117-
l.lowest_modified_value, l.greatest_modified_value
132+
UNION ALL
133+
SELECT 'materialization', ca.user_view_name,
134+
l.lowest_modified_value, l.greatest_modified_value,
135+
\if :has_inval_log_seqnum
136+
l.seqnum
137+
\else
138+
NULL::integer
139+
\endif
118140
FROM _timescaledb_catalog.continuous_aggs_materialization_invalidation_log l
119141
JOIN _timescaledb_catalog.continuous_agg ca ON ca.mat_hypertable_id = l.materialization_id
120-
WHERE ca.user_view_name IN ('mat_invallog_1', 'mat_invallog_2')
121-
ORDER BY 1, 2, 3;
142+
WHERE ca.user_view_name IN ('mat_invallog_1', 'mat_invallog_2');
143+
144+
SELECT name AS hypertable, lowest_modified_value, greatest_modified_value, seqnum
145+
FROM inval_log_live
146+
WHERE log = 'hypertable'
147+
ORDER BY 1, 2, 3, 4;
148+
149+
SELECT name AS cagg, lowest_modified_value, greatest_modified_value, seqnum
150+
FROM inval_log_live
151+
WHERE log = 'materialization'
152+
ORDER BY 1, 2, 3, 4;
122153

123154
-- Verify the live invalidation logs still hold exactly the rows
124155
-- snapshotted at the end of setup, i.e. an update script that rebuilds
125-
-- the log catalogs neither lost nor invented rows.
156+
-- the log catalogs neither lost nor invented rows. seqnum is part of the
157+
-- comparison: EXCEPT ALL compares rows with NULL treated as equal to
158+
-- NULL, so on versions without the column both sides are NULL and only
159+
-- the other values decide, while from 2.30 on a changed seqnum shows up
160+
-- as a row that is both missing and unexpected.
126161
DO $$
127162
DECLARE
128163
difference TEXT;
129164
BEGIN
130-
WITH live (log, name, lowest_modified_value, greatest_modified_value) AS (
131-
SELECT 'hypertable'::text, h.table_name,
132-
l.lowest_modified_value, l.greatest_modified_value
133-
FROM _timescaledb_catalog.continuous_aggs_hypertable_invalidation_log l
134-
JOIN _timescaledb_catalog.hypertable h ON h.id = l.hypertable_id
135-
WHERE h.table_name = 'inval_log_test'
136-
UNION ALL
137-
SELECT 'materialization', ca.user_view_name,
138-
l.lowest_modified_value, l.greatest_modified_value
139-
FROM _timescaledb_catalog.continuous_aggs_materialization_invalidation_log l
140-
JOIN _timescaledb_catalog.continuous_agg ca ON ca.mat_hypertable_id = l.materialization_id
141-
WHERE ca.user_view_name IN ('mat_invallog_1', 'mat_invallog_2')
142-
)
143-
SELECT string_agg(format('%s [%s]: (%s, %s, %s)', src, diff.log, diff.name,
144-
diff.lowest_modified_value, diff.greatest_modified_value), E'\n')
165+
SELECT string_agg(format('%s [%s]: (%s, %s, %s, seqnum %s)', src, diff.log, diff.name,
166+
diff.lowest_modified_value, diff.greatest_modified_value,
167+
coalesce(diff.seqnum::text, 'NULL')), E'\n')
145168
INTO difference
146169
FROM (
147170
SELECT 'missing after update' AS src, *
148171
FROM (SELECT * FROM inval_log_snapshot
149172
EXCEPT ALL
150-
SELECT * FROM live) missing
173+
SELECT * FROM inval_log_live) missing
151174
UNION ALL
152175
SELECT 'unexpected after update', *
153-
FROM (SELECT * FROM live
176+
FROM (SELECT * FROM inval_log_live
154177
EXCEPT ALL
155178
SELECT * FROM inval_log_snapshot) unexpected
156-
) diff (src, log, name, lowest_modified_value, greatest_modified_value);
179+
) diff (src, log, name, lowest_modified_value, greatest_modified_value, seqnum);
157180

158181
IF difference IS NOT NULL THEN
159182
RAISE EXCEPTION 'invalidation log content changed across the update'

test/sql/updates/setup.continuous_aggs.sql

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,16 +353,34 @@ FROM generate_series('2020-01-07 07:00:00+00'::timestamptz,
353353

354354
-- Snapshot invalidation log rows into a plain table so the post script can
355355
-- verify the live logs still hold the same content after the update rebuilt
356-
-- the catalogs.
356+
-- the catalogs. The seqnum column only exists from 2.30; on older versions
357+
-- record NULL, which is also what the 2.30 migration must leave in migrated
358+
-- rows and what the trigger writes when no granular tracking applies.
359+
SELECT EXISTS (
360+
SELECT FROM information_schema.columns
361+
WHERE table_schema = '_timescaledb_catalog'
362+
AND table_name = 'continuous_aggs_hypertable_invalidation_log'
363+
AND column_name = 'seqnum') AS has_inval_log_seqnum \gset
364+
357365
CREATE TABLE inval_log_snapshot AS
358366
SELECT 'hypertable'::text AS log, h.table_name AS name,
359-
l.lowest_modified_value, l.greatest_modified_value
367+
l.lowest_modified_value, l.greatest_modified_value,
368+
\if :has_inval_log_seqnum
369+
l.seqnum
370+
\else
371+
NULL::integer AS seqnum
372+
\endif
360373
FROM _timescaledb_catalog.continuous_aggs_hypertable_invalidation_log l
361374
JOIN _timescaledb_catalog.hypertable h ON h.id = l.hypertable_id
362375
WHERE h.table_name = 'inval_log_test'
363376
UNION ALL
364377
SELECT 'materialization', ca.user_view_name,
365-
l.lowest_modified_value, l.greatest_modified_value
378+
l.lowest_modified_value, l.greatest_modified_value,
379+
\if :has_inval_log_seqnum
380+
l.seqnum
381+
\else
382+
NULL::integer
383+
\endif
366384
FROM _timescaledb_catalog.continuous_aggs_materialization_invalidation_log l
367385
JOIN _timescaledb_catalog.continuous_agg ca ON ca.mat_hypertable_id = l.materialization_id
368386
WHERE ca.user_view_name IN ('mat_invallog_1', 'mat_invallog_2');

0 commit comments

Comments
 (0)