diff --git a/CHANGELOG.md b/CHANGELOG.md index acf4beec7..85ce7e2cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ accidentally triggering the load of a previous DB version.** ## Unreleased +If you use compression with a non-default collation on a segmentby-column you might have to recompress the affected hypertable. + **Features** * #4120 Add logging for retention policy * #4169 Add support for chunk exclusion on DELETE to PG14 @@ -15,6 +17,7 @@ accidentally triggering the load of a previous DB version.** * #3899 Fix segfault in Continuous Aggregates * #4225 Fix TRUNCATE error as non-owner on hypertable * #4259 Fix logic bug in extension update script +* #4236 Fix potential wrong order of results for compressed hypertable with a non-default collation **Thanks** * @jsoref for fixing various misspellings in code, comments and documentation diff --git a/scripts/test_update_from_tag.sh b/scripts/test_update_from_tag.sh index 9e7ded8c4..fca6e6466 100755 --- a/scripts/test_update_from_tag.sh +++ b/scripts/test_update_from_tag.sh @@ -88,7 +88,7 @@ docker_pgcmd() { docker_pgscript() { local database=${3:-single} - docker_exec $1 "psql -h localhost -U postgres -d $database $PGOPTS -v ON_ERROR_STOP=1 -f $2" + docker_exec $1 "psql --set VERBOSITY=verbose --set ECHO=all -h localhost -U postgres -d $database $PGOPTS -v ON_ERROR_STOP=1 -f $2" } docker_pgtest() { diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index b069674dc..7e319d4da 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -5,3 +5,70 @@ AS '@MODULE_PATHNAME@', 'ts_relation_size' LANGUAGE C VOLATILE; DROP VIEW IF EXISTS _timescaledb_internal.hypertable_chunk_local_size; DROP INDEX IF EXISTS _timescaledb_catalog.chunk_constraint_chunk_id_dimension_slice_id_idx; CREATE INDEX chunk_constraint_dimension_slice_id_idx ON _timescaledb_catalog.chunk_constraint (dimension_slice_id); + +-- Report the compressed chunks that have a wrong collation. See https://github.com/timescale/timescaledb/pull/4236 +DO $$ +DECLARE + _hypertable regclass; + _column_name text; + _chunks regclass[]; +BEGIN + FOR _hypertable, + _column_name, + _chunks IN +-- We materialize this CTE so that the filter on dropped chunks works +-- first, and we don't try to look up regclass for dropped chunks. +WITH chunk AS MATERIALIZED ( + SELECT + format('%I.%I', compressed_chunk.schema_name, compressed_chunk.table_name) compressed_chunk, + format('%I.%I', normal_chunk.schema_name, normal_chunk.table_name) normal_chunk, + normal_chunk.hypertable_id hypertable_id + FROM + _timescaledb_catalog.chunk normal_chunk, + _timescaledb_catalog.chunk compressed_chunk + WHERE + normal_chunk.compressed_chunk_id = compressed_chunk.id + AND NOT normal_chunk.dropped +), +col AS ( + SELECT + hypertable_id, + normal_chunk, + normal_column.attname column_name + FROM + chunk, + pg_attribute normal_column, + pg_attribute compressed_column + WHERE + normal_column.attrelid = normal_chunk::regclass + AND compressed_column.attrelid = compressed_chunk::regclass + AND normal_column.attname = compressed_column.attname + AND compressed_column.atttypid != '_timescaledb_internal.compressed_data'::regtype + AND normal_column.attcollation != compressed_column.attcollation +), +report_rows AS ( + SELECT + format('%I.%I', schema_name, table_name)::regclass hypertable, + normal_chunk::regclass chunk, + column_name + FROM + col, + _timescaledb_catalog.hypertable + WHERE + hypertable.id = hypertable_id +) +SELECT + hypertable, + column_name, + array_agg(chunk) chunks +FROM + report_rows +GROUP BY + hypertable, + column_name LOOP + RAISE warning 'some compressed chunks for hypertable "%" use a wrong collation for the column "%"', _hypertable, _column_name + USING detail = 'This may lead to wrong order of results if you are using an index on this column of the compessed chunk.', + hint = format('If you experience this problem, disable compression on the table and enable it again. This will require decompressing and compressing all chunks of the table. The affected chunks are "%s".', _chunks); +END LOOP; +END +$$;