396 lines
8.1 KiB
SQL
396 lines
8.1 KiB
SQL
# name: test/optimizer/date_trunc_simplification.test
|
|
# description: test DATE_TRUNC() constant simplifications
|
|
# group: [optimizer]
|
|
|
|
statement ok
|
|
PRAGMA enable_verification;
|
|
|
|
statement ok
|
|
PRAGMA explain_output = OPTIMIZED_ONLY;
|
|
|
|
statement ok
|
|
create table test(d TIMESTAMP);
|
|
|
|
statement ok
|
|
insert into test values ('2025-01-06 03:01:00'), ('2025-01-10 05:10:06');
|
|
|
|
#
|
|
# check correctness of simple optimizations
|
|
#
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) < '2025-01-08';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) <= '2025-01-06';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) > '2025-01-08';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) >= '2025-01-10';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) = '2025-01-06';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) != '2025-01-10';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) is not distinct from '2025-01-06';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) is distinct from '2025-01-10';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
#
|
|
# ensure date_trunc() is taken out of the result for all possible operators
|
|
#
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) < '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*Filters:[ \t\n│]*d<'2025.*$
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) <= '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*Filters:[ \t\n│]*d<='2025.*$
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) > '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*Filters:[ \t\n│]*d>='2025.*$
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) >= '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*Filters:[ \t\n│]*d>='2025.*$
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) = '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*Filters:[ \t\n│]*d>='2025.*AND.*d<'2025.*$
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) != '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*FILTER[ \t\n│─]*\(\(d >= '2025.*OR.*\(d <[ \t\n│─]*'2025.*$
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) is not distinct from '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*Filters:[ \t\n│]*d>='2025.*AND.*d<'2025.*$
|
|
|
|
query II
|
|
explain analyze select * from test where date_trunc('day', d) is distinct from '2025-01-08';
|
|
----
|
|
analyzed_plan <REGEX>:.*Filters:[ \t\n│─]*\(\(d >= '2025.*OR.*\(d <[ \t\n│─]*'2025.*$
|
|
|
|
#
|
|
# check correctness of simple optimizations, column on rhs
|
|
#
|
|
|
|
query I
|
|
select * from test where '2025-01-08' > date_trunc('day', d);
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where '2025-01-06' >= date_trunc('day', d);
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where '2025-01-08' < date_trunc('day', d);
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where '2025-01-10' <= date_trunc('day', d);
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where '2025-01-06' = date_trunc('day', d);
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where '2025-01-10' != date_trunc('day', d);
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where '2025-01-06' is not distinct from date_trunc('day', d);
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where '2025-01-10' is distinct from date_trunc('day', d);
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
#
|
|
# check correctness of optimizations with different input types
|
|
#
|
|
|
|
statement ok
|
|
create table test2(d DATE);
|
|
|
|
statement ok
|
|
insert into test2 values ('2025-01-06'), ('2025-01-10');
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) < '2025-01-08';
|
|
----
|
|
2025-01-06
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) <= '2025-01-06';
|
|
----
|
|
2025-01-06
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) > '2025-01-08';
|
|
----
|
|
2025-01-10
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) >= '2025-01-10';
|
|
----
|
|
2025-01-10
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) = '2025-01-06';
|
|
----
|
|
2025-01-06
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) != '2025-01-10';
|
|
----
|
|
2025-01-06
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) is not distinct from '2025-01-06';
|
|
----
|
|
2025-01-06
|
|
|
|
query I
|
|
select * from test2 where date_trunc('day', d) is distinct from '2025-01-10';
|
|
----
|
|
2025-01-06
|
|
|
|
#
|
|
# check edge cases
|
|
#
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) < '2025-01-06';
|
|
----
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) < '2025-01-07';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) <= '2025-01-06';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) <= '2025-01-07';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) > '2025-01-10';
|
|
----
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) > '2025-01-09';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) >= '2025-01-10';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) >= '2025-01-11';
|
|
----
|
|
|
|
query I
|
|
select * from test where date_trunc('hour', d) < '2025-01-06 03:00:00';
|
|
----
|
|
|
|
query I
|
|
select * from test where date_trunc('hour', d) < '2025-01-06 04:00:00';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('hour', d) <= '2025-01-06 03:00:00';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('hour', d) <= '2025-01-06 04:00:00';
|
|
----
|
|
2025-01-06 03:01:00
|
|
|
|
query I
|
|
select * from test where date_trunc('minute', d) > '2025-01-10 05:10:00';
|
|
----
|
|
|
|
query I
|
|
select * from test where date_trunc('minute', d) > '2025-01-10 05:09:00';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('minute', d) >= '2025-01-10 05:10:00';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('minute', d) >= '2025-01-10 05:11:00';
|
|
----
|
|
|
|
#
|
|
# check when there's a NULL in the table or on the RHS
|
|
#
|
|
|
|
statement ok
|
|
create table test3(d TIMESTAMP);
|
|
|
|
statement ok
|
|
insert into test3 values ('2025-01-06 03:01:00'), ('2025-01-10 05:10:06'), (NULL);
|
|
|
|
query I
|
|
select * from test3 where date_trunc('hour', d) = NULL;
|
|
----
|
|
|
|
query I
|
|
select * from test3 where date_trunc('hour', d) >= NULL;
|
|
----
|
|
|
|
query I
|
|
select * from test3 where date_trunc('hour', d) <= NULL;
|
|
----
|
|
|
|
query I
|
|
select * from test3 where date_trunc('hour', d) <> NULL;
|
|
----
|
|
|
|
query I
|
|
select * from test3 where date_trunc('hour', d) IS DISTINCT FROM NULL;
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test3 where date_trunc('hour', d) IS NOT DISTINCT FROM NULL;
|
|
----
|
|
NULL
|
|
|
|
#
|
|
# check that the optimization only applies if the LHS is just a column
|
|
#
|
|
|
|
query I
|
|
select * from test where date_trunc('day', date_add(d, INTERVAL 1 day)) >= '2025-01-12';
|
|
----
|
|
|
|
#
|
|
# check rewrites for any type of interval
|
|
#
|
|
|
|
query I
|
|
select * from test where date_trunc('year', d) >= '2024-01-01';
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('month', d) > '2025-01-01';
|
|
----
|
|
|
|
query I
|
|
select * from test where date_trunc('day', d) >= '2025-01-06';
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('decade', d) >= '2020-01-01';
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('century', d) >= '2000-01-01';
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('millennium', d) >= '2000-01-01';
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('microsecond', d) >= '2025-01-08';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('millisecond', d) >= '2025-01-08';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('second', d) >= '2025-01-08';
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('minute', d) > '2025-01-06 03:01:00'
|
|
----
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('hour', d) >= '2025-01-06 03:00:00';
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('week', d) >= '2025-01-01';
|
|
----
|
|
2025-01-06 03:01:00
|
|
2025-01-10 05:10:06
|
|
|
|
query I
|
|
select * from test where date_trunc('quarter', d) >= '2025-04-01';
|
|
----
|
|
|