# 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 :.*Filters:[ \t\n│]*d<'2025.*$ query II explain analyze select * from test where date_trunc('day', d) <= '2025-01-08'; ---- analyzed_plan :.*Filters:[ \t\n│]*d<='2025.*$ query II explain analyze select * from test where date_trunc('day', d) > '2025-01-08'; ---- analyzed_plan :.*Filters:[ \t\n│]*d>='2025.*$ query II explain analyze select * from test where date_trunc('day', d) >= '2025-01-08'; ---- analyzed_plan :.*Filters:[ \t\n│]*d>='2025.*$ query II explain analyze select * from test where date_trunc('day', d) = '2025-01-08'; ---- analyzed_plan :.*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 :.*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 :.*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 :.*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'; ----