Fix qual pushdown for compression

Operators used for qual pushdown for compressed chunks
should take the RHS expression's type into account.

Fixes #1855
This commit is contained in:
gayyappan 2020-04-27 23:36:02 -04:00 committed by gayyappan
parent 28e9a443b3
commit 49a56f7826
7 changed files with 663 additions and 5 deletions

View File

@ -4,6 +4,17 @@
`psql` with the `-X` flag to prevent any `.psqlrc` commands from
accidentally triggering the load of a previous DB version.**
## To be released
**Major Features**
**Bugfixes**
* #1850 Fix scheduler failure due to bad next_start_time for jobs
* #1861 Fix qual pushodwn for compressed hypertables where quals have casts
**Thanks**
* @frostwind for reporting issue with casts in where clauses on compressed hypertables
## 1.7.0 (2020-04-16)
This release adds major new features and bugfixes since the 1.6.1 release.

View File

@ -200,6 +200,7 @@ pushdown_op_to_segment_meta_min_max(QualPushdownContext *context, List *expr_arg
TypeCacheEntry *tce;
int strategy;
FormData_hypertable_compression *compression_info;
Oid expr_type_id;
if (list_length(expr_args) != 2)
return NULL;
@ -248,7 +249,7 @@ pushdown_op_to_segment_meta_min_max(QualPushdownContext *context, List *expr_arg
if (expr == NULL)
return NULL;
expr_type_id = exprType((Node *) expr);
switch (strategy)
{
case BTEqualStrategyNumber:
@ -256,11 +257,11 @@ pushdown_op_to_segment_meta_min_max(QualPushdownContext *context, List *expr_arg
/* var = expr implies min < expr and max > expr */
Oid opno_le = get_opfamily_member(tce->btree_opf,
tce->type_id,
tce->type_id,
expr_type_id,
BTLessEqualStrategyNumber);
Oid opno_ge = get_opfamily_member(tce->btree_opf,
tce->type_id,
tce->type_id,
expr_type_id,
BTGreaterEqualStrategyNumber);
if (!OidIsValid(opno_le) || !OidIsValid(opno_ge))
@ -289,7 +290,7 @@ pushdown_op_to_segment_meta_min_max(QualPushdownContext *context, List *expr_arg
/* var < expr implies min < expr */
{
Oid opno =
get_opfamily_member(tce->btree_opf, tce->type_id, tce->type_id, strategy);
get_opfamily_member(tce->btree_opf, tce->type_id, expr_type_id, strategy);
if (!OidIsValid(opno))
return NULL;
@ -311,7 +312,7 @@ pushdown_op_to_segment_meta_min_max(QualPushdownContext *context, List *expr_arg
/* var > expr implies max > expr */
{
Oid opno =
get_opfamily_member(tce->btree_opf, tce->type_id, tce->type_id, strategy);
get_opfamily_member(tce->btree_opf, tce->type_id, expr_type_id, strategy);
if (!OidIsValid(opno))
return NULL;

View File

@ -0,0 +1,183 @@
-- 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.
-- qual pushdown tests for decompresschunk ---
-- Test qual pushdown with ints
CREATE TABLE meta (device_id INT PRIMARY KEY);
CREATE TABLE hyper(
time INT NOT NULL,
device_id INT REFERENCES meta(device_id) ON DELETE CASCADE ON UPDATE CASCADE,
val INT);
SELECT * FROM create_hypertable('hyper', 'time', chunk_time_interval => 10);
hypertable_id | schema_name | table_name | created
---------------+-------------+------------+---------
1 | public | hyper | t
(1 row)
ALTER TABLE hyper SET (
timescaledb.compress,
timescaledb.compress_orderby = 'time',
timescaledb.compress_segmentby = 'device_id');
NOTICE: adding index _compressed_hypertable_2_device_id__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_2 USING BTREE(device_id, _ts_meta_sequence_num)
INSERT INTO meta VALUES (1), (2), (3), (4), (5);
INSERT INTO hyper VALUES (1, 1, 1), (2, 2, 1), (3, 3, 1), (10, 3, 2), (11, 4, 2), (11, 5, 2);
SELECT ch1.table_name AS "CHUNK_NAME", ch1.schema_name|| '.' || ch1.table_name AS "CHUNK_FULL_NAME"
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht
WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper'
ORDER BY ch1.id LIMIT 1 \gset
SELECT compress_chunk(:'CHUNK_FULL_NAME');
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_1_1_chunk
(1 row)
-- test for qual pushdown
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time > 2::bigint and time < 4;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk
Filter: ((_hyper_1_1_chunk."time" > '2'::bigint) AND (_hyper_1_1_chunk."time" < 4))
-> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk
Output: compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk."time"
Filter: ((compress_hyper_2_3_chunk._ts_meta_max_1 > '2'::bigint) AND (compress_hyper_2_3_chunk._ts_meta_min_1 < 4))
(6 rows)
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time = 3::bigint;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------
Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk
Filter: (_hyper_1_1_chunk."time" = '3'::bigint)
-> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk
Output: compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk."time"
Filter: ((compress_hyper_2_3_chunk._ts_meta_min_1 <= '3'::bigint) AND (compress_hyper_2_3_chunk._ts_meta_max_1 >= '3'::bigint))
(6 rows)
SELECT *
FROM hyper
WHERE time > 2::bigint and time < 4;
time | device_id | val
------+-----------+-----
3 | 3 | 1
(1 row)
SELECT *
FROM hyper
WHERE time = 3::bigint;
time | device_id | val
------+-----------+-----
3 | 3 | 1
(1 row)
--- github issue 1855
--- TESTs for meta column pushdown filters on exprs with casts.
CREATE TABLE metaseg_tab (
fmid smallint,
factorid smallint,
start_dt timestamp without time zone,
end_dt timestamp without time zone,
interval_number smallint,
logret double precision,
knowledge_date date NOT NULL
);
SELECT create_hypertable('metaseg_tab', 'end_dt', chunk_time_interval=>interval '1 month', create_default_indexes=>false);
NOTICE: adding not-null constraint to column "end_dt"
create_hypertable
--------------------------
(3,public,metaseg_tab,t)
(1 row)
SELECT add_dimension('metaseg_tab', 'fmid', chunk_time_interval => 1);
NOTICE: adding not-null constraint to column "fmid"
add_dimension
-------------------------------
(3,public,metaseg_tab,fmid,t)
(1 row)
ALTER TABLE metaseg_tab SET (timescaledb.compress, timescaledb.compress_orderby= 'end_dt');
INSERT INTO metaseg_tab values (56,0,'2012-12-10 09:45:00','2012-12-10 09:50:00',1,0.1,'2012-12-10');
SELECT compress_chunk(i) from show_chunks('metaseg_tab') i;
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_3_4_chunk
(1 row)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
factorid | end_dt | logret
----------+--------------------------+--------
0 | Mon Dec 10 09:50:00 2012 | 0.1
(1 row)
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Sort Key: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt
-> Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_3_4_chunk
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Filter: ((_hyper_3_4_chunk.end_dt >= '12-10-2012'::date) AND (_hyper_3_4_chunk.end_dt <= '12-11-2012'::date) AND (_hyper_3_4_chunk.fmid = 56))
-> Seq Scan on _timescaledb_internal.compress_hyper_4_5_chunk
Output: compress_hyper_4_5_chunk._ts_meta_count, compress_hyper_4_5_chunk.fmid, compress_hyper_4_5_chunk.factorid, compress_hyper_4_5_chunk.end_dt, compress_hyper_4_5_chunk.logret
Filter: ((compress_hyper_4_5_chunk._ts_meta_max_1 >= '12-10-2012'::date) AND (compress_hyper_4_5_chunk._ts_meta_min_1 <= '12-11-2012'::date))
(10 rows)
--no pushdown here
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
factorid | end_dt | logret
----------+--------------------------+--------
0 | Mon Dec 10 09:50:00 2012 | 0.1
(1 row)
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Sort Key: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt
-> Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_3_4_chunk
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Filter: ((_hyper_3_4_chunk.fmid = 56) AND ((_hyper_3_4_chunk.end_dt)::date >= 'Mon Dec 10 00:00:00 2012'::timestamp without time zone) AND ((_hyper_3_4_chunk.end_dt)::date <= '12-11-2012'::date))
-> Seq Scan on _timescaledb_internal.compress_hyper_4_5_chunk
Output: compress_hyper_4_5_chunk._ts_meta_count, compress_hyper_4_5_chunk.fmid, compress_hyper_4_5_chunk.factorid, compress_hyper_4_5_chunk.end_dt, compress_hyper_4_5_chunk.logret
(9 rows)
--should fail
\set ON_ERROR_STOP 0
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 10;
ERROR: operator does not exist: date = integer at character 84
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 'dec 2010'::date;
ERROR: invalid input syntax for type date: "dec 2010" at character 86

View File

@ -0,0 +1,183 @@
-- 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.
-- qual pushdown tests for decompresschunk ---
-- Test qual pushdown with ints
CREATE TABLE meta (device_id INT PRIMARY KEY);
CREATE TABLE hyper(
time INT NOT NULL,
device_id INT REFERENCES meta(device_id) ON DELETE CASCADE ON UPDATE CASCADE,
val INT);
SELECT * FROM create_hypertable('hyper', 'time', chunk_time_interval => 10);
hypertable_id | schema_name | table_name | created
---------------+-------------+------------+---------
1 | public | hyper | t
(1 row)
ALTER TABLE hyper SET (
timescaledb.compress,
timescaledb.compress_orderby = 'time',
timescaledb.compress_segmentby = 'device_id');
NOTICE: adding index _compressed_hypertable_2_device_id__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_2 USING BTREE(device_id, _ts_meta_sequence_num)
INSERT INTO meta VALUES (1), (2), (3), (4), (5);
INSERT INTO hyper VALUES (1, 1, 1), (2, 2, 1), (3, 3, 1), (10, 3, 2), (11, 4, 2), (11, 5, 2);
SELECT ch1.table_name AS "CHUNK_NAME", ch1.schema_name|| '.' || ch1.table_name AS "CHUNK_FULL_NAME"
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht
WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper'
ORDER BY ch1.id LIMIT 1 \gset
SELECT compress_chunk(:'CHUNK_FULL_NAME');
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_1_1_chunk
(1 row)
-- test for qual pushdown
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time > 2::bigint and time < 4;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk
Filter: ((_hyper_1_1_chunk."time" > '2'::bigint) AND (_hyper_1_1_chunk."time" < 4))
-> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk
Output: compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk."time"
Filter: ((compress_hyper_2_3_chunk._ts_meta_max_1 > '2'::bigint) AND (compress_hyper_2_3_chunk._ts_meta_min_1 < 4))
(6 rows)
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time = 3::bigint;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------
Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk
Filter: (_hyper_1_1_chunk."time" = '3'::bigint)
-> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk
Output: compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk."time"
Filter: ((compress_hyper_2_3_chunk._ts_meta_min_1 <= '3'::bigint) AND (compress_hyper_2_3_chunk._ts_meta_max_1 >= '3'::bigint))
(6 rows)
SELECT *
FROM hyper
WHERE time > 2::bigint and time < 4;
time | device_id | val
------+-----------+-----
3 | 3 | 1
(1 row)
SELECT *
FROM hyper
WHERE time = 3::bigint;
time | device_id | val
------+-----------+-----
3 | 3 | 1
(1 row)
--- github issue 1855
--- TESTs for meta column pushdown filters on exprs with casts.
CREATE TABLE metaseg_tab (
fmid smallint,
factorid smallint,
start_dt timestamp without time zone,
end_dt timestamp without time zone,
interval_number smallint,
logret double precision,
knowledge_date date NOT NULL
);
SELECT create_hypertable('metaseg_tab', 'end_dt', chunk_time_interval=>interval '1 month', create_default_indexes=>false);
NOTICE: adding not-null constraint to column "end_dt"
create_hypertable
--------------------------
(3,public,metaseg_tab,t)
(1 row)
SELECT add_dimension('metaseg_tab', 'fmid', chunk_time_interval => 1);
NOTICE: adding not-null constraint to column "fmid"
add_dimension
-------------------------------
(3,public,metaseg_tab,fmid,t)
(1 row)
ALTER TABLE metaseg_tab SET (timescaledb.compress, timescaledb.compress_orderby= 'end_dt');
INSERT INTO metaseg_tab values (56,0,'2012-12-10 09:45:00','2012-12-10 09:50:00',1,0.1,'2012-12-10');
SELECT compress_chunk(i) from show_chunks('metaseg_tab') i;
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_3_4_chunk
(1 row)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
factorid | end_dt | logret
----------+--------------------------+--------
0 | Mon Dec 10 09:50:00 2012 | 0.1
(1 row)
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Sort Key: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt
-> Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_3_4_chunk
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Filter: ((_hyper_3_4_chunk.end_dt >= '12-10-2012'::date) AND (_hyper_3_4_chunk.end_dt <= '12-11-2012'::date) AND (_hyper_3_4_chunk.fmid = 56))
-> Seq Scan on _timescaledb_internal.compress_hyper_4_5_chunk
Output: compress_hyper_4_5_chunk._ts_meta_count, compress_hyper_4_5_chunk.fmid, compress_hyper_4_5_chunk.factorid, compress_hyper_4_5_chunk.end_dt, compress_hyper_4_5_chunk.logret
Filter: ((compress_hyper_4_5_chunk._ts_meta_max_1 >= '12-10-2012'::date) AND (compress_hyper_4_5_chunk._ts_meta_min_1 <= '12-11-2012'::date))
(10 rows)
--no pushdown here
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
factorid | end_dt | logret
----------+--------------------------+--------
0 | Mon Dec 10 09:50:00 2012 | 0.1
(1 row)
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Sort Key: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt
-> Append
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_3_4_chunk
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Filter: ((_hyper_3_4_chunk.fmid = 56) AND ((_hyper_3_4_chunk.end_dt)::date >= 'Mon Dec 10 00:00:00 2012'::timestamp without time zone) AND ((_hyper_3_4_chunk.end_dt)::date <= '12-11-2012'::date))
-> Seq Scan on _timescaledb_internal.compress_hyper_4_5_chunk
Output: compress_hyper_4_5_chunk._ts_meta_count, compress_hyper_4_5_chunk.fmid, compress_hyper_4_5_chunk.factorid, compress_hyper_4_5_chunk.end_dt, compress_hyper_4_5_chunk.logret
(9 rows)
--should fail
\set ON_ERROR_STOP 0
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 10;
ERROR: operator does not exist: date = integer at character 84
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 'dec 2010'::date;
ERROR: invalid input syntax for type date: "dec 2010" at character 86

View File

@ -0,0 +1,179 @@
-- 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.
-- qual pushdown tests for decompresschunk ---
-- Test qual pushdown with ints
CREATE TABLE meta (device_id INT PRIMARY KEY);
CREATE TABLE hyper(
time INT NOT NULL,
device_id INT REFERENCES meta(device_id) ON DELETE CASCADE ON UPDATE CASCADE,
val INT);
SELECT * FROM create_hypertable('hyper', 'time', chunk_time_interval => 10);
hypertable_id | schema_name | table_name | created
---------------+-------------+------------+---------
1 | public | hyper | t
(1 row)
ALTER TABLE hyper SET (
timescaledb.compress,
timescaledb.compress_orderby = 'time',
timescaledb.compress_segmentby = 'device_id');
NOTICE: adding index _compressed_hypertable_2_device_id__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_2 USING BTREE(device_id, _ts_meta_sequence_num)
INSERT INTO meta VALUES (1), (2), (3), (4), (5);
INSERT INTO hyper VALUES (1, 1, 1), (2, 2, 1), (3, 3, 1), (10, 3, 2), (11, 4, 2), (11, 5, 2);
SELECT ch1.table_name AS "CHUNK_NAME", ch1.schema_name|| '.' || ch1.table_name AS "CHUNK_FULL_NAME"
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht
WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper'
ORDER BY ch1.id LIMIT 1 \gset
SELECT compress_chunk(:'CHUNK_FULL_NAME');
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_1_1_chunk
(1 row)
-- test for qual pushdown
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time > 2::bigint and time < 4;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk
Filter: ((_hyper_1_1_chunk."time" > '2'::bigint) AND (_hyper_1_1_chunk."time" < 4))
-> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk
Output: compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk."time"
Filter: ((compress_hyper_2_3_chunk._ts_meta_max_1 > '2'::bigint) AND (compress_hyper_2_3_chunk._ts_meta_min_1 < 4))
(5 rows)
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time = 3::bigint;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk
Filter: (_hyper_1_1_chunk."time" = '3'::bigint)
-> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk
Output: compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk."time"
Filter: ((compress_hyper_2_3_chunk._ts_meta_min_1 <= '3'::bigint) AND (compress_hyper_2_3_chunk._ts_meta_max_1 >= '3'::bigint))
(5 rows)
SELECT *
FROM hyper
WHERE time > 2::bigint and time < 4;
time | device_id | val
------+-----------+-----
3 | 3 | 1
(1 row)
SELECT *
FROM hyper
WHERE time = 3::bigint;
time | device_id | val
------+-----------+-----
3 | 3 | 1
(1 row)
--- github issue 1855
--- TESTs for meta column pushdown filters on exprs with casts.
CREATE TABLE metaseg_tab (
fmid smallint,
factorid smallint,
start_dt timestamp without time zone,
end_dt timestamp without time zone,
interval_number smallint,
logret double precision,
knowledge_date date NOT NULL
);
SELECT create_hypertable('metaseg_tab', 'end_dt', chunk_time_interval=>interval '1 month', create_default_indexes=>false);
NOTICE: adding not-null constraint to column "end_dt"
create_hypertable
--------------------------
(3,public,metaseg_tab,t)
(1 row)
SELECT add_dimension('metaseg_tab', 'fmid', chunk_time_interval => 1);
NOTICE: adding not-null constraint to column "fmid"
add_dimension
-------------------------------
(3,public,metaseg_tab,fmid,t)
(1 row)
ALTER TABLE metaseg_tab SET (timescaledb.compress, timescaledb.compress_orderby= 'end_dt');
INSERT INTO metaseg_tab values (56,0,'2012-12-10 09:45:00','2012-12-10 09:50:00',1,0.1,'2012-12-10');
SELECT compress_chunk(i) from show_chunks('metaseg_tab') i;
compress_chunk
----------------------------------------
_timescaledb_internal._hyper_3_4_chunk
(1 row)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
factorid | end_dt | logret
----------+--------------------------+--------
0 | Mon Dec 10 09:50:00 2012 | 0.1
(1 row)
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Sort Key: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_3_4_chunk
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Filter: ((_hyper_3_4_chunk.end_dt >= '12-10-2012'::date) AND (_hyper_3_4_chunk.end_dt <= '12-11-2012'::date) AND (_hyper_3_4_chunk.fmid = 56))
-> Seq Scan on _timescaledb_internal.compress_hyper_4_5_chunk
Output: compress_hyper_4_5_chunk._ts_meta_count, compress_hyper_4_5_chunk.fmid, compress_hyper_4_5_chunk.factorid, compress_hyper_4_5_chunk.end_dt, compress_hyper_4_5_chunk.logret
Filter: ((compress_hyper_4_5_chunk._ts_meta_max_1 >= '12-10-2012'::date) AND (compress_hyper_4_5_chunk._ts_meta_min_1 <= '12-11-2012'::date))
(9 rows)
--no pushdown here
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
factorid | end_dt | logret
----------+--------------------------+--------
0 | Mon Dec 10 09:50:00 2012 | 0.1
(1 row)
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Sort Key: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt
-> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_3_4_chunk
Output: _hyper_3_4_chunk.factorid, _hyper_3_4_chunk.end_dt, _hyper_3_4_chunk.logret
Filter: ((_hyper_3_4_chunk.fmid = 56) AND ((_hyper_3_4_chunk.end_dt)::date >= 'Mon Dec 10 00:00:00 2012'::timestamp without time zone) AND ((_hyper_3_4_chunk.end_dt)::date <= '12-11-2012'::date))
-> Seq Scan on _timescaledb_internal.compress_hyper_4_5_chunk
Output: compress_hyper_4_5_chunk._ts_meta_count, compress_hyper_4_5_chunk.fmid, compress_hyper_4_5_chunk.factorid, compress_hyper_4_5_chunk.end_dt, compress_hyper_4_5_chunk.logret
(8 rows)
--should fail
\set ON_ERROR_STOP 0
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 10;
ERROR: operator does not exist: date = integer at character 84
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 'dec 2010'::date;
ERROR: invalid input syntax for type date: "dec 2010" at character 86

View File

@ -64,6 +64,7 @@ if (${PG_VERSION_MAJOR} GREATER "9")
list(APPEND TEST_TEMPLATES
compression_permissions.sql.in
compression_qualpushdown.sql.in
)
if (CMAKE_BUILD_TYPE MATCHES Debug)
list(APPEND TEST_TEMPLATES

View File

@ -0,0 +1,100 @@
-- 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.
-- qual pushdown tests for decompresschunk ---
-- Test qual pushdown with ints
CREATE TABLE meta (device_id INT PRIMARY KEY);
CREATE TABLE hyper(
time INT NOT NULL,
device_id INT REFERENCES meta(device_id) ON DELETE CASCADE ON UPDATE CASCADE,
val INT);
SELECT * FROM create_hypertable('hyper', 'time', chunk_time_interval => 10);
ALTER TABLE hyper SET (
timescaledb.compress,
timescaledb.compress_orderby = 'time',
timescaledb.compress_segmentby = 'device_id');
INSERT INTO meta VALUES (1), (2), (3), (4), (5);
INSERT INTO hyper VALUES (1, 1, 1), (2, 2, 1), (3, 3, 1), (10, 3, 2), (11, 4, 2), (11, 5, 2);
SELECT ch1.table_name AS "CHUNK_NAME", ch1.schema_name|| '.' || ch1.table_name AS "CHUNK_FULL_NAME"
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht
WHERE ch1.hypertable_id = ht.id AND ht.table_name LIKE 'hyper'
ORDER BY ch1.id LIMIT 1 \gset
SELECT compress_chunk(:'CHUNK_FULL_NAME');
-- test for qual pushdown
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time > 2::bigint and time < 4;
explain (costs off, verbose)
SELECT
FROM hyper
WHERE time = 3::bigint;
SELECT *
FROM hyper
WHERE time > 2::bigint and time < 4;
SELECT *
FROM hyper
WHERE time = 3::bigint;
--- github issue 1855
--- TESTs for meta column pushdown filters on exprs with casts.
CREATE TABLE metaseg_tab (
fmid smallint,
factorid smallint,
start_dt timestamp without time zone,
end_dt timestamp without time zone,
interval_number smallint,
logret double precision,
knowledge_date date NOT NULL
);
SELECT create_hypertable('metaseg_tab', 'end_dt', chunk_time_interval=>interval '1 month', create_default_indexes=>false);
SELECT add_dimension('metaseg_tab', 'fmid', chunk_time_interval => 1);
ALTER TABLE metaseg_tab SET (timescaledb.compress, timescaledb.compress_orderby= 'end_dt');
INSERT INTO metaseg_tab values (56,0,'2012-12-10 09:45:00','2012-12-10 09:50:00',1,0.1,'2012-12-10');
SELECT compress_chunk(i) from show_chunks('metaseg_tab') i;
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt between '2012-12-10'::date and '2012-12-11'::date
order by factorid, end_dt;
--no pushdown here
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
explain (costs off, verbose)
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date between '2012-12-10'::timestamp and '2012-12-11'::date
order by factorid, end_dt;
--should fail
\set ON_ERROR_STOP 0
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 10;
select factorid, end_dt, logret
from metaseg_tab
where fmid = 56
and end_dt::date = 'dec 2010'::date;