Add test for jit compilation support

This test also covers a failure case descibed in the issue #1262.
This commit is contained in:
Dmitry Simonenko 2020-04-01 14:15:44 +03:00 committed by Erik Nordström
parent 21ebd9e68f
commit e2da5606cf
8 changed files with 627 additions and 1 deletions

View File

@ -0,0 +1,236 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
\set TEST_BASE_NAME jit
SELECT format('include/%s_load.sql', :'TEST_BASE_NAME') as "TEST_LOAD_NAME",
format('include/%s_query.sql', :'TEST_BASE_NAME') as "TEST_QUERY_NAME",
format('include/%s_cleanup.sql', :'TEST_BASE_NAME') as "TEST_CLEANUP_NAME",
format('%s/results/%s_results_optimized.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_OPTIMIZED",
format('%s/results/%s_results_unoptimized.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNOPTIMIZED"
\gset
SELECT format('\! diff -u --label "Unoptimized results" --label "Optimized results" %s %s', :'TEST_RESULTS_UNOPTIMIZED', :'TEST_RESULTS_OPTIMIZED') as "DIFF_CMD"
\gset
-- enable all jit optimizations
--
-- disable jit_tuple_deforming for PG11 as a temporary solution
-- until it fixed
--
SET jit=on;
SET jit_above_cost=0;
SET jit_inline_above_cost=0;
SET jit_optimize_above_cost=0;
SELECT
CASE WHEN current_setting('server_version_num')::int < 120000
THEN 0 ELSE 1
END AS "USE_JIT_DEFORMING"
\gset
SET jit_tuple_deforming=:USE_JIT_DEFORMING;
\ir :TEST_LOAD_NAME
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
CREATE TABLE jit_test(time timestamp NOT NULL, temp float);
SELECT create_hypertable('jit_test', 'time');
create_hypertable
-----------------------
(1,public,jit_test,t)
(1 row)
CREATE TABLE jit_test_interval(id int NOT NULL, temp float);
SELECT create_hypertable('jit_test_interval', 'id', chunk_time_interval => 10);
create_hypertable
--------------------------------
(2,public,jit_test_interval,t)
(1 row)
CREATE TABLE jit_test_contagg (
observation_time TIMESTAMPTZ NOT NULL,
device_id TEXT NOT NULL,
metric DOUBLE PRECISION NOT NULL,
PRIMARY KEY(observation_time, device_id)
);
SELECT table_name FROM create_hypertable('jit_test_contagg', 'observation_time');
table_name
------------------
jit_test_contagg
(1 row)
CREATE VIEW jit_device_summary
WITH (timescaledb.continuous)
AS
SELECT
time_bucket('1 hour', observation_time) as bucket,
device_id,
avg(metric) as metric_avg,
max(metric)-min(metric) as metric_spread
FROM
jit_test_contagg
GROUP BY bucket, device_id;
psql:include/jit_load.sql:28: NOTICE: adding index _materialized_hypertable_4_device_id_bucket_idx ON _timescaledb_internal._materialized_hypertable_4 USING BTREE(device_id, bucket)
INSERT INTO jit_test_contagg
SELECT ts, 'device_1', (EXTRACT(EPOCH FROM ts)) from generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '30 minutes') ts;
INSERT INTO jit_test_contagg
SELECT ts, 'device_2', (EXTRACT(EPOCH FROM ts)) from generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '30 minutes') ts;
ALTER VIEW jit_device_summary SET (timescaledb.max_interval_per_job = '60 day');
SET timescaledb.current_timestamp_mock = '2018-12-31 00:00';
REFRESH MATERIALIZED VIEW jit_device_summary;
\set PREFIX 'EXPLAIN (VERBOSE, TIMING OFF, COSTS OFF, SUMMARY OFF)'
\ir :TEST_QUERY_NAME
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
-- github issue #1262
--
:PREFIX
INSERT INTO jit_test VALUES('2017-01-20T09:00:01', 22.5) RETURNING *;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Custom Scan (HypertableInsert)
Output: "time", temp
-> Insert on public.jit_test
Output: "time", temp
-> Custom Scan (ChunkDispatch)
Output: 'Fri Jan 20 09:00:01 2017'::timestamp without time zone, '22.5'::double precision
-> Result
Output: 'Fri Jan 20 09:00:01 2017'::timestamp without time zone, '22.5'::double precision
(8 rows)
:PREFIX
INSERT INTO jit_test VALUES ('2017-01-20T09:00:02', 2),
('2017-01-20T09:00:03', 5),
('2017-01-20T09:00:04', 10);
QUERY PLAN
--------------------------------------------------------------------
Custom Scan (HypertableInsert)
-> Insert on public.jit_test
-> Custom Scan (ChunkDispatch)
Output: "*VALUES*".column1, "*VALUES*".column2
-> Values Scan on "*VALUES*"
Output: "*VALUES*".column1, "*VALUES*".column2
(6 rows)
:PREFIX
SELECT * FROM jit_test WHERE temp > 5 and temp <= 10 ORDER BY time;
QUERY PLAN
--------------------------------
Sort
Output: "time", temp
Sort Key: jit_test."time"
-> Result
Output: "time", temp
One-Time Filter: false
(6 rows)
-- update with iteration over chunks
--
:PREFIX
INSERT INTO jit_test_interval (SELECT x, x / 2.3 FROM generate_series(0, 100) x) RETURNING *;
QUERY PLAN
-------------------------------------------------------------------------
Custom Scan (HypertableInsert)
Output: jit_test_interval.id, jit_test_interval.temp
-> Insert on public.jit_test_interval
Output: jit_test_interval.id, jit_test_interval.temp
-> Custom Scan (ChunkDispatch)
Output: x.x, ((((x.x)::numeric / 2.3))::double precision)
-> Function Scan on pg_catalog.generate_series x
Output: x.x, ((x.x)::numeric / 2.3)
Function Call: generate_series(0, 100)
(9 rows)
:PREFIX
SELECT * FROM jit_test_interval WHERE id >= 23 and id < 73 ORDER BY id;
QUERY PLAN
----------------------------------
Sort
Output: id, temp
Sort Key: jit_test_interval.id
-> Result
Output: id, temp
One-Time Filter: false
(6 rows)
:PREFIX
UPDATE jit_test_interval SET temp = temp * 2.3 WHERE id >= 23 and id < 73;
QUERY PLAN
------------------------------------------------------------------------------------
Update on public.jit_test_interval
-> Index Scan using jit_test_interval_id_idx on public.jit_test_interval
Output: id, (temp * '2.3'::double precision), ctid
Index Cond: ((jit_test_interval.id >= 23) AND (jit_test_interval.id < 73))
(4 rows)
:PREFIX
SELECT * FROM jit_test_interval ORDER BY id;
QUERY PLAN
----------------------------------
Sort
Output: id, temp
Sort Key: jit_test_interval.id
-> Result
Output: id, temp
One-Time Filter: false
(6 rows)
:PREFIX
SELECT time_bucket(10, id), avg(temp)
FROM jit_test_interval
GROUP BY 1
ORDER BY 1;
QUERY PLAN
-----------------------------------------------------------
GroupAggregate
Output: (time_bucket(10, id)), avg(temp)
Group Key: (time_bucket(10, jit_test_interval.id))
-> Sort
Output: (time_bucket(10, id)), temp
Sort Key: (time_bucket(10, jit_test_interval.id))
-> Result
Output: time_bucket(10, id), temp
One-Time Filter: false
(9 rows)
-- test continuous aggregates usage with forced jit (based on continuous_aggs_usage.sql)
--
:PREFIX
SELECT * FROM jit_device_summary WHERE metric_spread = 1800 ORDER BY bucket DESC, device_id LIMIT 10;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, (_timescaledb_internal.finalize_agg('avg(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_3_3, NULL::double precision)), ((_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision)))
-> Sort
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, (_timescaledb_internal.finalize_agg('avg(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_3_3, NULL::double precision)), ((_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision)))
Sort Key: _materialized_hypertable_4.bucket DESC, _materialized_hypertable_4.device_id
-> Append
-> GroupAggregate
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, _timescaledb_internal.finalize_agg('avg(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_3_3, NULL::double precision), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision))
Group Key: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id
Filter: ((_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision)) = '1800'::double precision)
-> Sort
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, _materialized_hypertable_4.agg_3_3, _materialized_hypertable_4.agg_4_4, _materialized_hypertable_4.agg_4_5
Sort Key: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id
-> Custom Scan (ChunkAppend) on _timescaledb_internal._materialized_hypertable_4
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, _materialized_hypertable_4.agg_3_3, _materialized_hypertable_4.agg_4_4, _materialized_hypertable_4.agg_4_5
Startup Exclusion: true
Runtime Exclusion: false
Chunks excluded during startup: 0
-> Index Scan using _hyper_4_6_chunk__materialized_hypertable_4_bucket_idx on _timescaledb_internal._hyper_4_6_chunk
Output: _hyper_4_6_chunk.bucket, _hyper_4_6_chunk.device_id, _hyper_4_6_chunk.agg_3_3, _hyper_4_6_chunk.agg_4_4, _hyper_4_6_chunk.agg_4_5
Index Cond: (_hyper_4_6_chunk.bucket < COALESCE(_timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(3)), '-infinity'::timestamp with time zone))
-> HashAggregate
Output: (time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time)), jit_test_contagg.device_id, avg(jit_test_contagg.metric), (max(jit_test_contagg.metric) - min(jit_test_contagg.metric))
Group Key: time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time), jit_test_contagg.device_id
Filter: ((max(jit_test_contagg.metric) - min(jit_test_contagg.metric)) = '1800'::double precision)
-> Custom Scan (ChunkAppend) on public.jit_test_contagg
Output: time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time), jit_test_contagg.device_id, jit_test_contagg.metric
Startup Exclusion: true
Runtime Exclusion: false
Chunks excluded during startup: 4
-> Index Scan using _hyper_3_5_chunk_jit_test_contagg_observation_time_idx on _timescaledb_internal._hyper_3_5_chunk
Output: _hyper_3_5_chunk.observation_time, _hyper_3_5_chunk.device_id, _hyper_3_5_chunk.metric
Index Cond: (_hyper_3_5_chunk.observation_time >= COALESCE(_timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(3)), '-infinity'::timestamp with time zone))
(33 rows)
-- generate the results into two different files
\set ECHO errors
--TEST END--

View File

@ -0,0 +1,236 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
\set TEST_BASE_NAME jit
SELECT format('include/%s_load.sql', :'TEST_BASE_NAME') as "TEST_LOAD_NAME",
format('include/%s_query.sql', :'TEST_BASE_NAME') as "TEST_QUERY_NAME",
format('include/%s_cleanup.sql', :'TEST_BASE_NAME') as "TEST_CLEANUP_NAME",
format('%s/results/%s_results_optimized.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_OPTIMIZED",
format('%s/results/%s_results_unoptimized.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNOPTIMIZED"
\gset
SELECT format('\! diff -u --label "Unoptimized results" --label "Optimized results" %s %s', :'TEST_RESULTS_UNOPTIMIZED', :'TEST_RESULTS_OPTIMIZED') as "DIFF_CMD"
\gset
-- enable all jit optimizations
--
-- disable jit_tuple_deforming for PG11 as a temporary solution
-- until it fixed
--
SET jit=on;
SET jit_above_cost=0;
SET jit_inline_above_cost=0;
SET jit_optimize_above_cost=0;
SELECT
CASE WHEN current_setting('server_version_num')::int < 120000
THEN 0 ELSE 1
END AS "USE_JIT_DEFORMING"
\gset
SET jit_tuple_deforming=:USE_JIT_DEFORMING;
\ir :TEST_LOAD_NAME
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
CREATE TABLE jit_test(time timestamp NOT NULL, temp float);
SELECT create_hypertable('jit_test', 'time');
create_hypertable
-----------------------
(1,public,jit_test,t)
(1 row)
CREATE TABLE jit_test_interval(id int NOT NULL, temp float);
SELECT create_hypertable('jit_test_interval', 'id', chunk_time_interval => 10);
create_hypertable
--------------------------------
(2,public,jit_test_interval,t)
(1 row)
CREATE TABLE jit_test_contagg (
observation_time TIMESTAMPTZ NOT NULL,
device_id TEXT NOT NULL,
metric DOUBLE PRECISION NOT NULL,
PRIMARY KEY(observation_time, device_id)
);
SELECT table_name FROM create_hypertable('jit_test_contagg', 'observation_time');
table_name
------------------
jit_test_contagg
(1 row)
CREATE VIEW jit_device_summary
WITH (timescaledb.continuous)
AS
SELECT
time_bucket('1 hour', observation_time) as bucket,
device_id,
avg(metric) as metric_avg,
max(metric)-min(metric) as metric_spread
FROM
jit_test_contagg
GROUP BY bucket, device_id;
psql:include/jit_load.sql:28: NOTICE: adding index _materialized_hypertable_4_device_id_bucket_idx ON _timescaledb_internal._materialized_hypertable_4 USING BTREE(device_id, bucket)
INSERT INTO jit_test_contagg
SELECT ts, 'device_1', (EXTRACT(EPOCH FROM ts)) from generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '30 minutes') ts;
INSERT INTO jit_test_contagg
SELECT ts, 'device_2', (EXTRACT(EPOCH FROM ts)) from generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '30 minutes') ts;
ALTER VIEW jit_device_summary SET (timescaledb.max_interval_per_job = '60 day');
SET timescaledb.current_timestamp_mock = '2018-12-31 00:00';
REFRESH MATERIALIZED VIEW jit_device_summary;
\set PREFIX 'EXPLAIN (VERBOSE, TIMING OFF, COSTS OFF, SUMMARY OFF)'
\ir :TEST_QUERY_NAME
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
-- github issue #1262
--
:PREFIX
INSERT INTO jit_test VALUES('2017-01-20T09:00:01', 22.5) RETURNING *;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Custom Scan (HypertableInsert)
Output: jit_test."time", jit_test.temp
-> Insert on public.jit_test
Output: jit_test."time", jit_test.temp
-> Custom Scan (ChunkDispatch)
Output: 'Fri Jan 20 09:00:01 2017'::timestamp without time zone, '22.5'::double precision
-> Result
Output: 'Fri Jan 20 09:00:01 2017'::timestamp without time zone, '22.5'::double precision
(8 rows)
:PREFIX
INSERT INTO jit_test VALUES ('2017-01-20T09:00:02', 2),
('2017-01-20T09:00:03', 5),
('2017-01-20T09:00:04', 10);
QUERY PLAN
--------------------------------------------------------------------
Custom Scan (HypertableInsert)
-> Insert on public.jit_test
-> Custom Scan (ChunkDispatch)
Output: "*VALUES*".column1, "*VALUES*".column2
-> Values Scan on "*VALUES*"
Output: "*VALUES*".column1, "*VALUES*".column2
(6 rows)
:PREFIX
SELECT * FROM jit_test WHERE temp > 5 and temp <= 10 ORDER BY time;
QUERY PLAN
--------------------------------
Sort
Output: "time", temp
Sort Key: jit_test."time"
-> Result
Output: "time", temp
One-Time Filter: false
(6 rows)
-- update with iteration over chunks
--
:PREFIX
INSERT INTO jit_test_interval (SELECT x, x / 2.3 FROM generate_series(0, 100) x) RETURNING *;
QUERY PLAN
-------------------------------------------------------------------------
Custom Scan (HypertableInsert)
Output: jit_test_interval.id, jit_test_interval.temp
-> Insert on public.jit_test_interval
Output: jit_test_interval.id, jit_test_interval.temp
-> Custom Scan (ChunkDispatch)
Output: x.x, ((((x.x)::numeric / 2.3))::double precision)
-> Function Scan on pg_catalog.generate_series x
Output: x.x, ((x.x)::numeric / 2.3)
Function Call: generate_series(0, 100)
(9 rows)
:PREFIX
SELECT * FROM jit_test_interval WHERE id >= 23 and id < 73 ORDER BY id;
QUERY PLAN
----------------------------------
Sort
Output: id, temp
Sort Key: jit_test_interval.id
-> Result
Output: id, temp
One-Time Filter: false
(6 rows)
:PREFIX
UPDATE jit_test_interval SET temp = temp * 2.3 WHERE id >= 23 and id < 73;
QUERY PLAN
------------------------------------------------------------------------------------
Update on public.jit_test_interval
-> Index Scan using jit_test_interval_id_idx on public.jit_test_interval
Output: id, (temp * '2.3'::double precision), ctid
Index Cond: ((jit_test_interval.id >= 23) AND (jit_test_interval.id < 73))
(4 rows)
:PREFIX
SELECT * FROM jit_test_interval ORDER BY id;
QUERY PLAN
----------------------------------
Sort
Output: id, temp
Sort Key: jit_test_interval.id
-> Result
Output: id, temp
One-Time Filter: false
(6 rows)
:PREFIX
SELECT time_bucket(10, id), avg(temp)
FROM jit_test_interval
GROUP BY 1
ORDER BY 1;
QUERY PLAN
-----------------------------------------------------------
GroupAggregate
Output: (time_bucket(10, id)), avg(temp)
Group Key: (time_bucket(10, jit_test_interval.id))
-> Sort
Output: (time_bucket(10, id)), temp
Sort Key: (time_bucket(10, jit_test_interval.id))
-> Result
Output: time_bucket(10, id), temp
One-Time Filter: false
(9 rows)
-- test continuous aggregates usage with forced jit (based on continuous_aggs_usage.sql)
--
:PREFIX
SELECT * FROM jit_device_summary WHERE metric_spread = 1800 ORDER BY bucket DESC, device_id LIMIT 10;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, (_timescaledb_internal.finalize_agg('avg(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_3_3, NULL::double precision)), ((_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision)))
-> Sort
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, (_timescaledb_internal.finalize_agg('avg(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_3_3, NULL::double precision)), ((_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision)))
Sort Key: _materialized_hypertable_4.bucket DESC, _materialized_hypertable_4.device_id
-> Append
-> GroupAggregate
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, _timescaledb_internal.finalize_agg('avg(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_3_3, NULL::double precision), (_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision))
Group Key: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id
Filter: ((_timescaledb_internal.finalize_agg('max(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_4, NULL::double precision) - _timescaledb_internal.finalize_agg('min(double precision)'::text, NULL::name, NULL::name, '{{pg_catalog,float8}}'::name[], _materialized_hypertable_4.agg_4_5, NULL::double precision)) = '1800'::double precision)
-> Sort
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, _materialized_hypertable_4.agg_3_3, _materialized_hypertable_4.agg_4_4, _materialized_hypertable_4.agg_4_5
Sort Key: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id
-> Custom Scan (ChunkAppend) on _timescaledb_internal._materialized_hypertable_4
Output: _materialized_hypertable_4.bucket, _materialized_hypertable_4.device_id, _materialized_hypertable_4.agg_3_3, _materialized_hypertable_4.agg_4_4, _materialized_hypertable_4.agg_4_5
Startup Exclusion: true
Runtime Exclusion: false
Chunks excluded during startup: 0
-> Index Scan using _hyper_4_6_chunk__materialized_hypertable_4_bucket_idx on _timescaledb_internal._hyper_4_6_chunk
Output: _hyper_4_6_chunk.bucket, _hyper_4_6_chunk.device_id, _hyper_4_6_chunk.agg_3_3, _hyper_4_6_chunk.agg_4_4, _hyper_4_6_chunk.agg_4_5
Index Cond: (_hyper_4_6_chunk.bucket < COALESCE(_timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(3)), '-infinity'::timestamp with time zone))
-> HashAggregate
Output: (time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time)), jit_test_contagg.device_id, avg(jit_test_contagg.metric), (max(jit_test_contagg.metric) - min(jit_test_contagg.metric))
Group Key: time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time), jit_test_contagg.device_id
Filter: ((max(jit_test_contagg.metric) - min(jit_test_contagg.metric)) = '1800'::double precision)
-> Custom Scan (ChunkAppend) on public.jit_test_contagg
Output: time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time), jit_test_contagg.device_id, jit_test_contagg.metric
Startup Exclusion: true
Runtime Exclusion: false
Chunks excluded during startup: 4
-> Index Scan using _hyper_3_5_chunk_jit_test_contagg_observation_time_idx on _timescaledb_internal._hyper_3_5_chunk
Output: _hyper_3_5_chunk.observation_time, _hyper_3_5_chunk.device_id, _hyper_3_5_chunk.metric
Index Cond: (_hyper_3_5_chunk.observation_time >= COALESCE(_timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(3)), '-infinity'::timestamp with time zone))
(33 rows)
-- generate the results into two different files
\set ECHO errors
--TEST END--

View File

@ -7,3 +7,4 @@
/compression_permissions-*.sql
/move-*.sql
/reorder-*.sql
/jit-*.sql

View File

@ -29,6 +29,16 @@ set(TEST_TEMPLATES
reorder.sql.in
)
# Check if PostgreSQL was compiled with JIT support
set(PG_CONFIG_H "${PG_INCLUDEDIR}/pg_config.h")
if (EXISTS ${PG_CONFIG_H})
file(STRINGS "${PG_CONFIG_H}" PG_USE_LLVM
REGEX "^#[\t ]*define[\t ]+USE_LLVM[\t ]+1.*")
if (PG_USE_LLVM AND ${PG_VERSION_MAJOR} GREATER_EQUAL "11")
list(APPEND TEST_TEMPLATES jit.sql.in)
endif()
endif()
if (CMAKE_BUILD_TYPE MATCHES Debug)
list(APPEND TEST_TEMPLATES
#current_timestamp_mock available only in debug mode
@ -36,7 +46,6 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
)
endif(CMAKE_BUILD_TYPE MATCHES Debug)
#compression only for PG > 9
if (${PG_VERSION_MAJOR} GREATER "9")

View File

@ -0,0 +1,7 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
DROP TABLE IF EXISTS jit_test CASCADE;
DROP TABLE IF EXISTS jit_test_interval CASCADE;
DROP TABLE IF EXISTS jit_test_contagg CASCADE;

View File

@ -0,0 +1,37 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
CREATE TABLE jit_test(time timestamp NOT NULL, temp float);
SELECT create_hypertable('jit_test', 'time');
CREATE TABLE jit_test_interval(id int NOT NULL, temp float);
SELECT create_hypertable('jit_test_interval', 'id', chunk_time_interval => 10);
CREATE TABLE jit_test_contagg (
observation_time TIMESTAMPTZ NOT NULL,
device_id TEXT NOT NULL,
metric DOUBLE PRECISION NOT NULL,
PRIMARY KEY(observation_time, device_id)
);
SELECT table_name FROM create_hypertable('jit_test_contagg', 'observation_time');
CREATE VIEW jit_device_summary
WITH (timescaledb.continuous)
AS
SELECT
time_bucket('1 hour', observation_time) as bucket,
device_id,
avg(metric) as metric_avg,
max(metric)-min(metric) as metric_spread
FROM
jit_test_contagg
GROUP BY bucket, device_id;
INSERT INTO jit_test_contagg
SELECT ts, 'device_1', (EXTRACT(EPOCH FROM ts)) from generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '30 minutes') ts;
INSERT INTO jit_test_contagg
SELECT ts, 'device_2', (EXTRACT(EPOCH FROM ts)) from generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '30 minutes') ts;
ALTER VIEW jit_device_summary SET (timescaledb.max_interval_per_job = '60 day');
SET timescaledb.current_timestamp_mock = '2018-12-31 00:00';
REFRESH MATERIALIZED VIEW jit_device_summary;

View File

@ -0,0 +1,41 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
-- github issue #1262
--
:PREFIX
INSERT INTO jit_test VALUES('2017-01-20T09:00:01', 22.5) RETURNING *;
:PREFIX
INSERT INTO jit_test VALUES ('2017-01-20T09:00:02', 2),
('2017-01-20T09:00:03', 5),
('2017-01-20T09:00:04', 10);
:PREFIX
SELECT * FROM jit_test WHERE temp > 5 and temp <= 10 ORDER BY time;
-- update with iteration over chunks
--
:PREFIX
INSERT INTO jit_test_interval (SELECT x, x / 2.3 FROM generate_series(0, 100) x) RETURNING *;
:PREFIX
SELECT * FROM jit_test_interval WHERE id >= 23 and id < 73 ORDER BY id;
:PREFIX
UPDATE jit_test_interval SET temp = temp * 2.3 WHERE id >= 23 and id < 73;
:PREFIX
SELECT * FROM jit_test_interval ORDER BY id;
:PREFIX
SELECT time_bucket(10, id), avg(temp)
FROM jit_test_interval
GROUP BY 1
ORDER BY 1;
-- test continuous aggregates usage with forced jit (based on continuous_aggs_usage.sql)
--
:PREFIX
SELECT * FROM jit_device_summary WHERE metric_spread = 1800 ORDER BY bucket DESC, device_id LIMIT 10;

59
tsl/test/sql/jit.sql.in Normal file
View File

@ -0,0 +1,59 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
\set TEST_BASE_NAME jit
SELECT format('include/%s_load.sql', :'TEST_BASE_NAME') as "TEST_LOAD_NAME",
format('include/%s_query.sql', :'TEST_BASE_NAME') as "TEST_QUERY_NAME",
format('include/%s_cleanup.sql', :'TEST_BASE_NAME') as "TEST_CLEANUP_NAME",
format('%s/results/%s_results_optimized.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_OPTIMIZED",
format('%s/results/%s_results_unoptimized.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_UNOPTIMIZED"
\gset
SELECT format('\! diff -u --label "Unoptimized results" --label "Optimized results" %s %s', :'TEST_RESULTS_UNOPTIMIZED', :'TEST_RESULTS_OPTIMIZED') as "DIFF_CMD"
\gset
-- enable all jit optimizations
--
-- disable jit_tuple_deforming for PG11 as a temporary solution
-- until it fixed
--
SET jit=on;
SET jit_above_cost=0;
SET jit_inline_above_cost=0;
SET jit_optimize_above_cost=0;
SELECT
CASE WHEN current_setting('server_version_num')::int < 120000
THEN 0 ELSE 1
END AS "USE_JIT_DEFORMING"
\gset
SET jit_tuple_deforming=:USE_JIT_DEFORMING;
\ir :TEST_LOAD_NAME
\set PREFIX 'EXPLAIN (VERBOSE, TIMING OFF, COSTS OFF, SUMMARY OFF)'
\ir :TEST_QUERY_NAME
-- generate the results into two different files
\set ECHO errors
SET client_min_messages TO error;
\set PREFIX ''
-- get query results with jit enabled
\o :TEST_RESULTS_OPTIMIZED
\ir :TEST_QUERY_NAME
\o
-- disable jit optimizations and repeat
SET jit=off;
\o /dev/null
\ir :TEST_CLEANUP_NAME
\ir :TEST_LOAD_NAME
\o :TEST_RESULTS_UNOPTIMIZED
\ir :TEST_QUERY_NAME
\o
-- compare jit vs non-jit output
:DIFF_CMD
\set ECHO queries
\qecho '--TEST END--'