mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 18:43:18 +08:00
Fix time_bucket comparison transformation
The time_bucket comparison transformation code assumed the value and the width of the time_bucket comparison expression were both Const. But this was not validated only asserted. This can lead to wrong query results. Found by sqlsmith.
This commit is contained in:
parent
0f5268ad49
commit
7591f7f1f3
@ -11,8 +11,9 @@ accidentally triggering the load of a previous DB version.**
|
||||
* #3769 Allow ALTER TABLE DROP COLUMN on compressed hypertable
|
||||
|
||||
**Bugfixes**
|
||||
* #3766 Fix segfault in ts_hist_sfunc
|
||||
* #3739 Fix compression policy on tables using INTEGER
|
||||
* #3766 Fix segfault in ts_hist_sfunc
|
||||
* #3789 Fix time_bucket comparison transformation
|
||||
|
||||
**Thanks**
|
||||
* @cbisnett for reporting and fixing a typo in an error message
|
||||
|
@ -318,8 +318,8 @@ transform_time_bucket_comparison(PlannerInfo *root, OpExpr *op)
|
||||
TypeCacheEntry *tce;
|
||||
int strategy;
|
||||
|
||||
/* caller must ensure time_bucket only has 2 arguments */
|
||||
Assert(list_length(time_bucket->args) == 2);
|
||||
if (list_length(time_bucket->args) != 2 || !IsA(value, Const) || !IsA(width, Const))
|
||||
return op;
|
||||
|
||||
/*
|
||||
* if time_bucket call is on wrong side we switch operator
|
||||
@ -359,11 +359,6 @@ transform_time_bucket_comparison(PlannerInfo *root, OpExpr *op)
|
||||
Datum datum;
|
||||
int64 integralValue, integralWidth;
|
||||
|
||||
/*
|
||||
* caller should make sure value and width are Const
|
||||
*/
|
||||
Assert(IsA(value, Const) && IsA(width, Const));
|
||||
|
||||
if (castNode(Const, value)->constisnull || width->constisnull)
|
||||
return op;
|
||||
|
||||
|
@ -1391,6 +1391,47 @@ time_bucket exclusion with timestamptz and day interval
|
||||
Filter: ((time_bucket('@ 1 day'::interval, "time") >= 'Mon Jan 03 00:00:00 2000 PST'::timestamp with time zone) AND (time_bucket('@ 7 days'::interval, "time") <= 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone))
|
||||
(11 rows)
|
||||
|
||||
\qecho no transformation
|
||||
no transformation
|
||||
:PREFIX SELECT * FROM hyper WHERE time_bucket(10 + floor(random())::int, time) > 10 AND time_bucket(10 + floor(random())::int, time) < 100 AND time < 150 ORDER BY time;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Sort
|
||||
Sort Key: hyper."time"
|
||||
-> Custom Scan (ChunkAppend) on hyper
|
||||
Chunks excluded during startup: 0
|
||||
-> Seq Scan on _hyper_1_1_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_2_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_3_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_4_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_5_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_6_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_7_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_8_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_9_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_10_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_11_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_12_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_13_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_14_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_15_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
(34 rows)
|
||||
|
||||
\qecho exclude chunks based on time column with partitioning function. This
|
||||
exclude chunks based on time column with partitioning function. This
|
||||
\qecho transparently applies the time partitioning function on the time
|
||||
|
@ -1391,6 +1391,47 @@ time_bucket exclusion with timestamptz and day interval
|
||||
Filter: ((time_bucket('@ 1 day'::interval, "time") >= 'Mon Jan 03 00:00:00 2000 PST'::timestamp with time zone) AND (time_bucket('@ 7 days'::interval, "time") <= 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone))
|
||||
(11 rows)
|
||||
|
||||
\qecho no transformation
|
||||
no transformation
|
||||
:PREFIX SELECT * FROM hyper WHERE time_bucket(10 + floor(random())::int, time) > 10 AND time_bucket(10 + floor(random())::int, time) < 100 AND time < 150 ORDER BY time;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Sort
|
||||
Sort Key: hyper."time"
|
||||
-> Custom Scan (ChunkAppend) on hyper
|
||||
Chunks excluded during startup: 0
|
||||
-> Seq Scan on _hyper_1_1_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_2_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_3_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_4_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_5_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_6_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_7_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_8_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_9_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_10_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_11_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_12_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_13_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_14_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_15_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
(34 rows)
|
||||
|
||||
\qecho exclude chunks based on time column with partitioning function. This
|
||||
exclude chunks based on time column with partitioning function. This
|
||||
\qecho transparently applies the time partitioning function on the time
|
||||
|
@ -1391,6 +1391,47 @@ time_bucket exclusion with timestamptz and day interval
|
||||
Filter: ((time_bucket('@ 1 day'::interval, "time") >= 'Mon Jan 03 00:00:00 2000 PST'::timestamp with time zone) AND (time_bucket('@ 7 days'::interval, "time") <= 'Mon Jan 10 00:00:00 2000 PST'::timestamp with time zone))
|
||||
(11 rows)
|
||||
|
||||
\qecho no transformation
|
||||
no transformation
|
||||
:PREFIX SELECT * FROM hyper WHERE time_bucket(10 + floor(random())::int, time) > 10 AND time_bucket(10 + floor(random())::int, time) < 100 AND time < 150 ORDER BY time;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Sort
|
||||
Sort Key: hyper."time"
|
||||
-> Custom Scan (ChunkAppend) on hyper
|
||||
Chunks excluded during startup: 0
|
||||
-> Seq Scan on _hyper_1_1_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_2_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_3_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_4_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_5_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_6_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_7_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_8_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_9_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_10_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_11_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_12_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_13_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_14_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
-> Seq Scan on _hyper_1_15_chunk
|
||||
Filter: (("time" < 150) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") > 10) AND (time_bucket(((10 + (floor(random()))::integer))::bigint, "time") < 100))
|
||||
(34 rows)
|
||||
|
||||
\qecho exclude chunks based on time column with partitioning function. This
|
||||
exclude chunks based on time column with partitioning function. This
|
||||
\qecho transparently applies the time partitioning function on the time
|
||||
|
@ -202,6 +202,9 @@ SELECT * FROM cte ORDER BY value;
|
||||
:PREFIX SELECT time FROM metrics_timestamptz WHERE time_bucket('1d',time) >= '2000-01-03' AND time_bucket('1d',time) <= '2000-01-10' ORDER BY time;
|
||||
:PREFIX SELECT time FROM metrics_timestamptz WHERE time_bucket('1d',time) >= '2000-01-03' AND time_bucket('7d',time) <= '2000-01-10' ORDER BY time;
|
||||
|
||||
\qecho no transformation
|
||||
:PREFIX SELECT * FROM hyper WHERE time_bucket(10 + floor(random())::int, time) > 10 AND time_bucket(10 + floor(random())::int, time) < 100 AND time < 150 ORDER BY time;
|
||||
|
||||
\qecho exclude chunks based on time column with partitioning function. This
|
||||
\qecho transparently applies the time partitioning function on the time
|
||||
\qecho value to be able to exclude chunks (similar to a closed dimension).
|
||||
|
Loading…
x
Reference in New Issue
Block a user