From a118f384c15b902265bdd7927330af4984181f0a Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Wed, 6 Oct 2021 03:26:05 +0200 Subject: [PATCH] Fix index attnum mapping in reorder_chunk When we clone an index from a chunk we must not do attnum mapping if the supplied index template is not on the hypertable. Ideally we would check for the template being on the chunk but we cannot do that since when we rebuild a chunk the new chunk has a different id. Fixes #3651 --- CHANGELOG.md | 5 +++++ src/chunk_index.c | 14 +++++++++++++- tsl/test/expected/reorder.out | 17 +++++++++++++++++ tsl/test/sql/reorder.sql | 9 +++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc052c75385..94fa0926700 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ `psql` with the `-X` flag to prevent any `.psqlrc` commands from accidentally triggering the load of a previous DB version.** +## Unreleased + +**Bugfixes** +* #3654 Fix index attnum mapping in reorder_chunk + ## 2.4.2 (2021-09-21) This release contains bug fixes since the 2.4.1 release. diff --git a/src/chunk_index.c b/src/chunk_index.c index 8ed9e251cb5..04382f11ddd 100644 --- a/src/chunk_index.c +++ b/src/chunk_index.c @@ -207,12 +207,24 @@ chunk_relation_index_create(Relation htrel, Relation template_indexrel, Relation { IndexInfo *indexinfo = BuildIndexInfo(template_indexrel); int32 hypertable_id; + bool skip_mapping = false; + + /* + * If the supplied template index is not on the hypertable we must not do attnum + * mapping based on the hypertable. Ideally we would check for the template being + * on the chunk but we cannot do that since when we rebuild a chunk the new chunk + * has a different id. But the template index should always be either on the + * hypertable or on a relation with the same physical layout as chunkrel. + */ + if (IndexGetRelation(template_indexrel->rd_id, false) != htrel->rd_id) + skip_mapping = true; /* * Convert the IndexInfo's attnos to match the chunk instead of the * hypertable */ - if (chunk_index_need_attnos_adjustment(RelationGetDescr(htrel), RelationGetDescr(chunkrel))) + if (!skip_mapping && + chunk_index_need_attnos_adjustment(RelationGetDescr(htrel), RelationGetDescr(chunkrel))) ts_adjust_indexinfo_attnos(indexinfo, htrel->rd_id, chunkrel); hypertable_id = ts_hypertable_relid_to_id(htrel->rd_id); diff --git a/tsl/test/expected/reorder.out b/tsl/test/expected/reorder.out index 5456b1fa018..da13c4f35a7 100644 --- a/tsl/test/expected/reorder.out +++ b/tsl/test/expected/reorder.out @@ -1344,3 +1344,20 @@ WHERE indisclustered = true ORDER BY 1; SELECT reorder_chunk('_timescaledb_internal._hyper_2_3_chunk', verbose => TRUE); ERROR: must be owner of hypertable "ct2" \set ON_ERROR_STOP 1 +-- #3651 incorrect index attribute mapping in reorder_chunk +CREATE TABLE i3651(c1 timestamptz NOT NULL,c2 text, c3 text, c4 text); +SELECT table_name FROM create_hypertable('i3651','c1'); + table_name +------------ + i3651 +(1 row) + +ALTER TABLE i3651 drop column c2; +CREATE UNIQUE INDEX i3651_attmap ON i3651(c1,c4); +INSERT INTO i3651 VALUES('2000-01-01','foo','foo'),('2000-01-01','foo','bar'); +SELECT reorder_chunk(chunk,'i3651_attmap') from show_chunks('i3651') chunk; + reorder_chunk +--------------- + +(1 row) + diff --git a/tsl/test/sql/reorder.sql b/tsl/test/sql/reorder.sql index 73d410955c8..252762bbc91 100644 --- a/tsl/test/sql/reorder.sql +++ b/tsl/test/sql/reorder.sql @@ -245,3 +245,12 @@ WHERE indisclustered = true ORDER BY 1; \set ON_ERROR_STOP 0 SELECT reorder_chunk('_timescaledb_internal._hyper_2_3_chunk', verbose => TRUE); \set ON_ERROR_STOP 1 + +-- #3651 incorrect index attribute mapping in reorder_chunk +CREATE TABLE i3651(c1 timestamptz NOT NULL,c2 text, c3 text, c4 text); +SELECT table_name FROM create_hypertable('i3651','c1'); +ALTER TABLE i3651 drop column c2; +CREATE UNIQUE INDEX i3651_attmap ON i3651(c1,c4); +INSERT INTO i3651 VALUES('2000-01-01','foo','foo'),('2000-01-01','foo','bar'); +SELECT reorder_chunk(chunk,'i3651_attmap') from show_chunks('i3651') chunk; +