Skip to content

Commit

Permalink
Fix missing varlen header in DimensionInfo
Browse files Browse the repository at this point in the history
The SQL data type _timescaledb_internal.dimension_info is declared with
INTERNALLENGTH = VARIABLE. This requires a varlen header, which was
missing. Therefore, the needed space of the function result was not
handled properly. This commit introduces the missing header.
  • Loading branch information
jnidzwetzki committed Feb 27, 2024
1 parent c81ddeb commit a7e274c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/dimension.c
Original file line number Diff line number Diff line change
Expand Up @@ -1748,7 +1748,10 @@ ts_dimension_info_out(PG_FUNCTION_ARGS)
static DimensionInfo *
make_dimension_info(Name colname, DimensionType dimtype)
{
DimensionInfo *info = palloc0(sizeof(DimensionInfo));
size_t size = sizeof(DimensionInfo);
DimensionInfo *info = palloc0(size);
SET_VARSIZE(info, size);

info->type = dimtype;
namestrcpy(&info->colname, NameStr(*colname));
return info;
Expand Down
5 changes: 5 additions & 0 deletions src/dimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ typedef struct Hypertable Hypertable;
*/
typedef struct DimensionInfo
{
/* We declare the SQL type dimension_info with INTERNALLENGTH = VARIABLE.
* So, PostgreSQL expects a proper length info field (varlena header).
*/
int32 vl_len_;

Oid table_relid;
int32 dimension_id;
NameData colname;
Expand Down
25 changes: 25 additions & 0 deletions tsl/test/expected/hypertable_generalization.out
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,31 @@ SELECT by_hash('id', 3, partition_func => 'part_func');
hash//id//3//part_func
(1 row)

-- Check if we handle the varlength of the datatype properly
SELECT * FROM by_range('id') WHERE by_range IS NOT NULL;
by_range
-----------------
range//id//-//-
(1 row)

SELECT * FROM by_range('id', partition_func => 'part_func') WHERE by_range IS NOT NULL;
by_range
-------------------------
range//id//-//part_func
(1 row)

SELECT * FROM by_hash('id', 3) WHERE by_hash IS NOT NULL;
by_hash
----------------
hash//id//3//-
(1 row)

SELECT * FROM by_hash('id', 3, partition_func => 'part_func') WHERE by_hash IS NOT NULL;
by_hash
------------------------
hash//id//3//part_func
(1 row)

\set ON_ERROR_STOP 0
SELECT 'hash//id//3//-'::_timescaledb_internal.dimension_info;
ERROR: cannot construct type "dimension_info" from string at character 8
Expand Down
6 changes: 6 additions & 0 deletions tsl/test/sql/hypertable_generalization.sql
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ SELECT by_range('id', '1 week'::interval, 'part_func'::regproc);
SELECT by_hash('id', 3);
SELECT by_hash('id', 3, partition_func => 'part_func');

-- Check if we handle the varlength of the datatype properly
SELECT * FROM by_range('id') WHERE by_range IS NOT NULL;
SELECT * FROM by_range('id', partition_func => 'part_func') WHERE by_range IS NOT NULL;
SELECT * FROM by_hash('id', 3) WHERE by_hash IS NOT NULL;
SELECT * FROM by_hash('id', 3, partition_func => 'part_func') WHERE by_hash IS NOT NULL;

\set ON_ERROR_STOP 0
SELECT 'hash//id//3//-'::_timescaledb_internal.dimension_info;
SELECT by_range(NULL::name);
Expand Down

0 comments on commit a7e274c

Please sign in to comment.