Skip to content

Commit

Permalink
Add tests for defaults and generated column values
Browse files Browse the repository at this point in the history
This adds basic tests for generated columns and columns with default
values.
  • Loading branch information
mkindahl committed Nov 20, 2024
1 parent 9ac073f commit 4261541
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 37 deletions.
55 changes: 36 additions & 19 deletions tsl/test/expected/hypercore.out
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ CREATE TABLE readings(
device int,
temp numeric(4,1),
humidity float,
jdata jsonb
jdata jsonb,
temp_far float8 generated always as (9 * temp / 5 + 32) stored
);
SELECT create_hypertable('readings', by_range('time', '1d'::interval));
NOTICE: adding not-null constraint to column "time"
Expand Down Expand Up @@ -180,7 +181,7 @@ SET enable_indexscan = false;
-- Columnar scan with qual on segmentby where filtering should be
-- turned into scankeys
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
QUERY PLAN
------------------------------------------------------------
Limit
Expand All @@ -190,7 +191,7 @@ SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
Scankey: (device < 4)
(5 rows)

SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:55:00 2022 PDT | 1 | 1 | 18.1 | 93.2399098726618 | {"a": 1, "b": 2}
Expand All @@ -205,7 +206,7 @@ SET enable_indexscan = true;
SET enable_seqscan = false;
SET timescaledb.enable_columnarscan = false;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
QUERY PLAN
--------------------------------------------------------------------------
Limit
Expand All @@ -215,7 +216,7 @@ SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
Filter: (device < 4)
(5 rows)

SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:55:00 2022 PDT | 1 | 1 | 18.1 | 93.2399098726618 | {"a": 1, "b": 2}
Expand All @@ -230,7 +231,7 @@ SET enable_indexscan = false;
-- shown further down.
SET timescaledb.enable_transparent_decompression TO 'hypercore';
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
QUERY PLAN
--------------------------------------------------------------------------
Limit
Expand All @@ -243,7 +244,7 @@ SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
Filter: (device < 4)
(8 rows)

SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:55:00 2022 PDT | 1 | 1 | 18.1 | 93.2399098726618 | {"a": 1, "b": 2}
Expand All @@ -257,7 +258,7 @@ SET timescaledb.enable_transparent_decompression TO false;
-- Qual on compressed column with index
SET timescaledb.enable_columnarscan = true;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
QUERY PLAN
------------------------------------------------------------
Limit
Expand All @@ -267,7 +268,7 @@ SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
Vectorized Filter: (location < 4)
(5 rows)

SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:25:00 2022 PDT | 3 | 5 | 23.5 | 76.360064629636 | {"a": 1, "b": 2}
Expand All @@ -281,7 +282,7 @@ SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SET enable_indexscan = true;
SET timescaledb.enable_columnarscan = false;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
QUERY PLAN
-----------------------------------------------------------------------------------------
Limit
Expand All @@ -291,7 +292,7 @@ SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
Index Cond: (location < 4)
(5 rows)

SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:25:00 2022 PDT | 3 | 5 | 23.5 | 76.360064629636 | {"a": 1, "b": 2}
Expand All @@ -306,7 +307,7 @@ SET enable_seqscan = true;
SET timescaledb.enable_columnarscan = true;
-- With transparent decompression
SET timescaledb.enable_transparent_decompression TO 'hypercore';
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:25:00 2022 PDT | 3 | 5 | 23.5 | 76.360064629636 | {"a": 1, "b": 2}
Expand All @@ -320,14 +321,14 @@ SET timescaledb.enable_transparent_decompression TO false;
-- Ordering on compressed column that has index
SET enable_indexscan = true;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk ORDER BY location ASC LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk ORDER BY location ASC LIMIT 5;
QUERY PLAN
-----------------------------------------------------------------------------------
Limit
-> Index Scan using _hyper_1_1_chunk_readings_location_idx on _hyper_1_1_chunk
(2 rows)

SELECT * FROM :chunk ORDER BY location ASC LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk ORDER BY location ASC LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:55:00 2022 PDT | 1 | 1 | 18.1 | 93.2399098726618 | {"a": 1, "b": 2}
Expand All @@ -339,7 +340,7 @@ SELECT * FROM :chunk ORDER BY location ASC LIMIT 5;

-- Show with transparent decompression
SET timescaledb.enable_transparent_decompression TO 'hypercore';
SELECT * FROM :chunk ORDER BY location ASC LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk ORDER BY location ASC LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 13:40:00 2022 PDT | 1 | 4 | 12.8 | 37.4106484592863 | {"a": 1, "b": 2}
Expand Down Expand Up @@ -399,6 +400,13 @@ WHERE format('%I.%I', c.schema_name, c.table_name)::regclass = :'chunk'::regclas
0
(1 row)

-- Check that the generated columns contain the correct data before
-- compression.
select temp, temp_far from :chunk where temp_far != 9 * temp / 5 + 32;
temp | temp_far
------+----------
(0 rows)

SELECT compress_chunk(:'chunk');
compress_chunk
----------------------------------------
Expand All @@ -415,8 +423,15 @@ ON (c1.compressed_chunk_id = c2.id);
_timescaledb_internal.compress_hyper_2_33_chunk
(1 row)

-- Check that the generated columns contain the correct data after
-- compression.
select temp, temp_far from :chunk where temp_far != 9 * temp / 5 + 32;
temp | temp_far
------+----------
(0 rows)

-- Show same output as first query above but for heap
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
time | location | device | temp | humidity | jdata
------------------------------+----------+--------+------+------------------+------------------
Wed Jun 01 00:55:00 2022 PDT | 1 | 1 | 18.1 | 93.2399098726618 | {"a": 1, "b": 2}
Expand Down Expand Up @@ -461,6 +476,8 @@ WHERE format('%I.%I', chunk_schema, chunk_name)::regclass = :'chunk'::regclass;
Tue May 31 17:00:00 2022 PDT | Wed Jun 01 17:00:00 2022 PDT
(1 row)

-- Drop the generated column to make tests below easier.
alter table readings drop column temp_far;
--
-- ADD COLUMN
--
Expand Down Expand Up @@ -538,7 +555,7 @@ SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
Wed Jun 01 00:06:15 2022 PDT | 2 | 24 | 36.7 | 74.3169985385593 | | 7.30696097227121
(1 row)

-- Drop column and add again
-- Drop column and add again, with a default this time
ALTER TABLE readings DROP COLUMN pressure;
EXPLAIN (verbose, costs off)
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
Expand All @@ -555,7 +572,7 @@ SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
Wed Jun 01 00:06:15 2022 PDT | 2 | 24 | 36.7 | 74.3169985385593 |
(1 row)

ALTER TABLE readings ADD COLUMN pressure float;
ALTER TABLE readings ADD COLUMN pressure float default 1.0;
EXPLAIN (verbose, costs off)
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
QUERY PLAN
Expand All @@ -568,7 +585,7 @@ SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
time | location | device | temp | humidity | jdata | pressure
------------------------------+----------+--------+------+------------------+-------+----------
Wed Jun 01 00:06:15 2022 PDT | 2 | 24 | 36.7 | 74.3169985385593 | |
Wed Jun 01 00:06:15 2022 PDT | 2 | 24 | 36.7 | 74.3169985385593 | | 1
(1 row)

\set ON_ERROR_STOP 0
Expand Down
48 changes: 30 additions & 18 deletions tsl/test/sql/hypercore.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ CREATE TABLE readings(
device int,
temp numeric(4,1),
humidity float,
jdata jsonb
jdata jsonb,
temp_far float8 generated always as (9 * temp / 5 + 32) stored
);

SELECT create_hypertable('readings', by_range('time', '1d'::interval));
Expand Down Expand Up @@ -117,56 +118,56 @@ SET enable_indexscan = false;
-- Columnar scan with qual on segmentby where filtering should be
-- turned into scankeys
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;

-- Show with indexscan
SET enable_indexscan = true;
SET enable_seqscan = false;
SET timescaledb.enable_columnarscan = false;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SET enable_indexscan = false;

-- Compare the output to transparent decompression. Heap output is
-- shown further down.
SET timescaledb.enable_transparent_decompression TO 'hypercore';
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SET timescaledb.enable_transparent_decompression TO false;

-- Qual on compressed column with index
SET timescaledb.enable_columnarscan = true;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;

-- With index scan
SET enable_indexscan = true;
SET timescaledb.enable_columnarscan = false;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SET enable_indexscan = false;
SET enable_seqscan = true;
SET timescaledb.enable_columnarscan = true;

-- With transparent decompression
SET timescaledb.enable_transparent_decompression TO 'hypercore';
SELECT * FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE location < 4 ORDER BY time, device LIMIT 5;
SET timescaledb.enable_transparent_decompression TO false;

-- Ordering on compressed column that has index
SET enable_indexscan = true;
EXPLAIN (costs off, timing off, summary off)
SELECT * FROM :chunk ORDER BY location ASC LIMIT 5;
SELECT * FROM :chunk ORDER BY location ASC LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk ORDER BY location ASC LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk ORDER BY location ASC LIMIT 5;

-- Show with transparent decompression
SET timescaledb.enable_transparent_decompression TO 'hypercore';
SELECT * FROM :chunk ORDER BY location ASC LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk ORDER BY location ASC LIMIT 5;
SET timescaledb.enable_transparent_decompression TO false;

-- We should be able to change it back to heap.
Expand Down Expand Up @@ -201,6 +202,10 @@ SELECT count(*) FROM _timescaledb_catalog.compression_chunk_size ccs
INNER JOIN _timescaledb_catalog.chunk c ON (c.id = ccs.chunk_id)
WHERE format('%I.%I', c.schema_name, c.table_name)::regclass = :'chunk'::regclass;

-- Check that the generated columns contain the correct data before
-- compression.
select temp, temp_far from :chunk where temp_far != 9 * temp / 5 + 32;

SELECT compress_chunk(:'chunk');

-- A new compressed chunk should be created
Expand All @@ -209,8 +214,12 @@ FROM _timescaledb_catalog.chunk c1
INNER JOIN _timescaledb_catalog.chunk c2
ON (c1.compressed_chunk_id = c2.id);

-- Check that the generated columns contain the correct data after
-- compression.
select temp, temp_far from :chunk where temp_far != 9 * temp / 5 + 32;

-- Show same output as first query above but for heap
SELECT * FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;
SELECT time, location, device, temp, humidity, jdata FROM :chunk WHERE device < 4 ORDER BY time, device LIMIT 5;

-- Show access method used on chunk
SELECT c.relname, a.amname FROM pg_class c
Expand Down Expand Up @@ -239,6 +248,9 @@ SELECT range_start, range_end
FROM timescaledb_information.chunks
WHERE format('%I.%I', chunk_schema, chunk_name)::regclass = :'chunk'::regclass;

-- Drop the generated column to make tests below easier.
alter table readings drop column temp_far;

--
-- ADD COLUMN
--
Expand Down Expand Up @@ -285,14 +297,14 @@ EXPLAIN (verbose, costs off)
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;

-- Drop column and add again
-- Drop column and add again, with a default this time
ALTER TABLE readings DROP COLUMN pressure;

EXPLAIN (verbose, costs off)
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;

ALTER TABLE readings ADD COLUMN pressure float;
ALTER TABLE readings ADD COLUMN pressure float default 1.0;

EXPLAIN (verbose, costs off)
SELECT * FROM :chunk WHERE time = '2022-06-01 00:06:15'::timestamptz;
Expand Down

0 comments on commit 4261541

Please sign in to comment.