Skip to content

Commit

Permalink
Server crash when using duplicate segmentby column
Browse files Browse the repository at this point in the history
The segmentby column info array is populated by using the column
attribute number as an array index. This is done as part of validating
and creating segment by column info in function `compresscolinfo_init`.

Since the column is duplicated the attribute number for both the
segmentby column is same. When this attribute number is used as an
index, only one of the array element is populated correctly with the
detailed column info whareas the other element of the array ramins
NULL. This segmentby column info is updated in catalog as part of
processing compression options (ALTER TABLE ...).

When the chunk is being compressed this segmentby column information is
being retrieved from the catalog to create the scan key in order to
identify any existing index on the table that matches the segmentby
column. Out of the two keys one key gets updated correctly whereas the
second key contains NULL values. This results into a crash during index
scan to identify any existing index on the table.

The proposed change avoid this crash by raising an error if user has
specified duplicated columns as part of compress_segmentby option.
  • Loading branch information
pdipesh02 committed Sep 5, 2023
1 parent e66a400 commit ccc4f48
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 0 deletions.
1 change: 1 addition & 0 deletions .unreleased/bugfix_6044
@@ -0,0 +1 @@
Fixes: #6044 Server crash when using duplicate segmentby column
8 changes: 8 additions & 0 deletions tsl/src/compression/create.c
Expand Up @@ -245,6 +245,14 @@ compresscolinfo_init(CompressColInfo *cc, Oid srctbl_relid, List *segmentby_cols
errhint("The timescaledb.compress_segmentby option must reference a valid "
"column.")));
}

/* Check if a column is duplicated in segment by column list. */
if (segorder_colindex[col_attno - 1] != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("duplicate column name \"%s\"", NameStr(col->colname)),
errhint("The timescaledb.compress_segmentby option must reference distinct "
"column.")));
segorder_colindex[col_attno - 1] = i++;
}
/* the column indexes are numbered as seg_attnolen + <orderby_index>
Expand Down
3 changes: 3 additions & 0 deletions tsl/test/expected/compression_errors.out
Expand Up @@ -195,6 +195,9 @@ HINT: The option timescaledb.compress_segmentby must be a set of columns separa
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, p');
ERROR: invalid ordering column type point
DETAIL: Could not identify a less-than operator for the type.
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'b, b');
ERROR: duplicate column name "b"
HINT: The timescaledb.compress_segmentby option must reference distinct column.
--should succeed
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, b');
--ddl on ht with compression
Expand Down
1 change: 1 addition & 0 deletions tsl/test/sql/compression_errors.sql
Expand Up @@ -99,6 +99,7 @@ ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'ran
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'c LIMIT 1');
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'c + b');
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, p');
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'b, b');

--should succeed
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, b');
Expand Down

0 comments on commit ccc4f48

Please sign in to comment.