Files
email-tracker/external/duckdb/test/optimizer/date_trunc_simplification.test
2025-10-24 19:21:19 -05:00

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';
----