Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix chunk index column name mapping #3082

Merged
merged 2 commits into from Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,9 +10,11 @@ accidentally triggering the load of a previous DB version.**
* #2989 Refactor and harden size and stats functions
* #3058 Reduce memory usage for distributed inserts
* #3067 Fix extremely slow multi-node order by queries
* #3082 Fix chunk index column name mapping
* #3083 Keep Append pathkeys in ChunkAppend

**Thanks**
* @BowenGG for reporting an issue with indexes with INCLUDE
* @fvannee for reporting an issue with ChunkAppend pathkeys
* @pedrokost and @RobAtticus for reporting an issue with size
functions on empty hypertables
Expand Down
36 changes: 21 additions & 15 deletions src/chunk_index.c
Expand Up @@ -123,24 +123,30 @@ adjust_expr_attnos(Oid ht_relid, IndexInfo *ii, Relation chunkrel)
* Adjust column reference attribute numbers for regular indexes.
*/
static void
chunk_adjust_colref_attnos(IndexInfo *ii, Relation idxrel, Relation chunkrel)
chunk_adjust_colref_attnos(IndexInfo *ii, Oid ht_relid, Relation chunkrel)
{
int i;

for (i = 0; i < idxrel->rd_att->natts; i++)
for (i = 0; i < ii->ii_NumIndexAttrs; i++)
{
FormData_pg_attribute *idxattr = TupleDescAttr(idxrel->rd_att, i);
AttrNumber attno = get_attnum(chunkrel->rd_id, NameStr(idxattr->attname));
/* zeroes indicate expressions */
if (ii->ii_IndexAttrNumbers[i] == 0)
continue;
/* we must not use get_attname on the index here as the index column names
* are independent of parent relation column names. Instead we need to look
* up the attno of the referenced hypertable column and do the matching
* with the hypertable column name */
char *colname = get_attname(ht_relid, ii->ii_IndexAttrNumbers[i], false);
AttrNumber attno = get_attnum(chunkrel->rd_id, colname);

if (attno == InvalidAttrNumber)
elog(ERROR, "index attribute %s not found in chunk", NameStr(idxattr->attname));
elog(ERROR, "index attribute %s not found in chunk", colname);
ii->ii_IndexAttrNumbers[i] = attno;
}
}

void
ts_adjust_indexinfo_attnos(IndexInfo *indexinfo, Oid ht_relid, Relation template_indexrel,
Relation chunkrel)
ts_adjust_indexinfo_attnos(IndexInfo *indexinfo, Oid ht_relid, Relation chunkrel)
{
/*
* Adjust a hypertable's index attribute numbers to match a chunk.
Expand All @@ -151,15 +157,15 @@ ts_adjust_indexinfo_attnos(IndexInfo *indexinfo, Oid ht_relid, Relation template
* IndexInfo from a hypertable's index to create a corresponding index on a
* chunk, we need to adjust the attribute numbers to match the chunk.
*
* We need to handle two cases: (1) regular indexes that reference columns
* directly, and (2) expression indexes that reference columns in expressions.
*
* Additionally we need to adjust column references in predicates.
* We need to handle 3 places:
* - direct column references in ii_IndexAttrNumbers
* - references in expressions in ii_Expressions
* - references in expressions in ii_Predicate
*/
if (list_length(indexinfo->ii_Expressions) == 0)
chunk_adjust_colref_attnos(indexinfo, template_indexrel, chunkrel);
chunk_adjust_colref_attnos(indexinfo, ht_relid, chunkrel);

adjust_expr_attnos(ht_relid, indexinfo, chunkrel);
if (indexinfo->ii_Expressions || indexinfo->ii_Predicate)
adjust_expr_attnos(ht_relid, indexinfo, chunkrel);
}

#define CHUNK_INDEX_TABLESPACE_OFFSET 1
Expand Down Expand Up @@ -213,7 +219,7 @@ chunk_relation_index_create(Relation htrel, Relation template_indexrel, Relation
* hypertable
*/
if (chunk_index_need_attnos_adjustment(RelationGetDescr(htrel), RelationGetDescr(chunkrel)))
ts_adjust_indexinfo_attnos(indexinfo, htrel->rd_id, template_indexrel, chunkrel);
ts_adjust_indexinfo_attnos(indexinfo, htrel->rd_id, chunkrel);

hypertable_id = ts_hypertable_relid_to_id(htrel->rd_id);

Expand Down
3 changes: 1 addition & 2 deletions src/chunk_index.h
Expand Up @@ -29,8 +29,7 @@ typedef struct ChunkIndexMapping
extern void ts_chunk_index_create(Relation hypertable_rel, int32 hypertable_id,
Relation hypertable_idxrel, int32 chunk_id, Relation chunkrel);

void ts_adjust_indexinfo_attnos(IndexInfo *indexinfo, Oid ht_relid, Relation template_indexrel,
Relation chunkrel);
void ts_adjust_indexinfo_attnos(IndexInfo *indexinfo, Oid ht_relid, Relation chunkrel);
extern void ts_chunk_index_create_from_adjusted_index_info(int32 hypertable_id,
Relation hypertable_idxrel,
int32 chunk_id, Relation chunkrel,
Expand Down
10 changes: 2 additions & 8 deletions src/process_utility.c
Expand Up @@ -2041,10 +2041,7 @@ process_index_chunk(Hypertable *ht, Oid chunk_relid, void *arg)
if (chunk_index_columns_changed(info->extended_options.n_ht_atts,
info->extended_options.ht_hasoid,
RelationGetDescr(chunk_rel)))
ts_adjust_indexinfo_attnos(indexinfo,
info->main_table_relid,
hypertable_index_rel,
chunk_rel);
ts_adjust_indexinfo_attnos(indexinfo, info->main_table_relid, chunk_rel);

ts_chunk_index_create_from_adjusted_index_info(ht->fd.id,
hypertable_index_rel,
Expand Down Expand Up @@ -2133,10 +2130,7 @@ process_index_chunk_multitransaction(int32 hypertable_id, Oid chunk_relid, void
if (chunk_index_columns_changed(info->extended_options.n_ht_atts,
info->extended_options.ht_hasoid,
RelationGetDescr(chunk_rel)))
ts_adjust_indexinfo_attnos(indexinfo,
info->main_table_relid,
hypertable_index_rel,
chunk_rel);
ts_adjust_indexinfo_attnos(indexinfo, info->main_table_relid, chunk_rel);

ts_chunk_index_create_from_adjusted_index_info(hypertable_id,
hypertable_index_rel,
Expand Down
12 changes: 12 additions & 0 deletions test/expected/index.out
Expand Up @@ -710,3 +710,15 @@ ORDER BY
_timescaledb_internal._hyper_13_19_chunk | _timescaledb_internal._hyper_13_19_chunk_ht_dropped_c0_c1_c2_idx1 | {c0,c1,c2} | | f | f | f |
(9 rows)

-- #3056 check chunk index column name mapping
CREATE TABLE i3056(c int, order_number int NOT NULL, date_created timestamptz NOT NULL);
CREATE INDEX ON i3056(order_number) INCLUDE(order_number);
CREATE INDEX ON i3056(date_created, (order_number % 5)) INCLUDE(order_number);
SELECT table_name FROM create_hypertable('i3056', 'date_created');
table_name
------------
i3056
(1 row)

ALTER TABLE i3056 DROP COLUMN c;
INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01');
5 changes: 3 additions & 2 deletions test/pgtest/CMakeLists.txt
Expand Up @@ -24,12 +24,13 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/testtablespace)

# Tests to ignore
set(PG_IGNORE_TESTS
advisory_lock
foreign_data
identity
opr_sanity
rolenames
rules
opr_sanity
sanity_check
foreign_data
security_label
)

Expand Down
9 changes: 9 additions & 0 deletions test/sql/index.sql
Expand Up @@ -330,3 +330,12 @@ FROM
ORDER BY
1, 2;

-- #3056 check chunk index column name mapping
CREATE TABLE i3056(c int, order_number int NOT NULL, date_created timestamptz NOT NULL);
CREATE INDEX ON i3056(order_number) INCLUDE(order_number);
CREATE INDEX ON i3056(date_created, (order_number % 5)) INCLUDE(order_number);
SELECT table_name FROM create_hypertable('i3056', 'date_created');
ALTER TABLE i3056 DROP COLUMN c;
INSERT INTO i3056(order_number,date_created) VALUES (1, '2000-01-01');