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; +