@@ -1726,6 +1726,44 @@ impl RewriteRules for FilterRules {
17261726 "?filter_aliases" ,
17271727 ) ,
17281728 ) ,
1729+ // EXTRACT(YEAR FROM "KibanaSampleDataEcommerce"."order_date") = 2019
1730+ // AND EXTRACT(MONTH FROM "KibanaSampleDataEcommerce"."order_date") = 3
1731+ transforming_rewrite(
1732+ "extract-date-range-and-gran-equals" ,
1733+ filter_op(
1734+ filter_op_filters(
1735+ filter_member( "?member" , "FilterMemberOp:inDateRange" , "?values" ) ,
1736+ filter_replacer(
1737+ binary_expr(
1738+ self . fun_expr(
1739+ "DatePart" ,
1740+ vec![ literal_expr( "?granularity" ) , column_expr( "?column" ) ] ,
1741+ ) ,
1742+ "=" ,
1743+ literal_expr( "?value" ) ,
1744+ ) ,
1745+ "?alias_to_cube" ,
1746+ "?members" ,
1747+ "?filter_aliases" ,
1748+ ) ,
1749+ ) ,
1750+ "FilterOpOp:and" ,
1751+ ) ,
1752+ filter_member( "?member" , "FilterMemberOp:inDateRange" , "?new_values" ) ,
1753+ self . transform_filter_extract_date_range_and_trunc_gran_equals(
1754+ "?member" ,
1755+ "?values" ,
1756+ "?granularity" ,
1757+ "?column" ,
1758+ "?value" ,
1759+ "?alias_to_cube" ,
1760+ "?members" ,
1761+ "?filter_aliases" ,
1762+ "?new_values" ,
1763+ ) ,
1764+ ) ,
1765+ // TODO: Introduce rule to unwrap TRUNC(EXTRACT(?granularity FROM ?column_expr))
1766+ //
17291767 // TRUNC(EXTRACT(YEAR FROM "KibanaSampleDataEcommerce"."order_date")) = 2019
17301768 // AND TRUNC(EXTRACT(MONTH FROM "KibanaSampleDataEcommerce"."order_date")) = 3
17311769 transforming_rewrite(
@@ -1765,6 +1803,7 @@ impl RewriteRules for FilterRules {
17651803 "?new_values" ,
17661804 ) ,
17671805 ) ,
1806+ // TODO: Introduce rule to unwrap TRUNC(EXTRACT(?granularity FROM ?column_expr))
17681807 // When the filter set above is paired with other filters, it needs to be
17691808 // regrouped for the above rewrite rule to match
17701809 rewrite(
@@ -1829,6 +1868,7 @@ impl RewriteRules for FilterRules {
18291868 "FilterOpOp:and" ,
18301869 ) ,
18311870 ) ,
1871+ // TODO: Introduce rule to unwrap TRUNC(EXTRACT(?granularity FROM ?column_expr))
18321872 // The filter set above may be inverted, let's account for that as well
18331873 rewrite(
18341874 "extract-date-range-and-trunc-reverse" ,
@@ -1877,6 +1917,7 @@ impl RewriteRules for FilterRules {
18771917 "FilterOpOp:and" ,
18781918 ) ,
18791919 ) ,
1920+ // TODO: Introduce rule to unwrap TRUNC(EXTRACT(?granularity FROM ?column_expr))
18801921 rewrite(
18811922 "extract-date-range-and-trunc-reverse-nested" ,
18821923 filter_op(
@@ -3991,6 +4032,7 @@ impl FilterRules {
39914032 if start_date_year != end_date. year ( ) {
39924033 return false ;
39934034 }
4035+
39944036 // Month value must be valid
39954037 if !( 1 ..=12 ) . contains ( & value) {
39964038 return false ;
@@ -4022,6 +4064,48 @@ impl FilterRules {
40224064 new_end_date. format( "%Y-%m-%d" ) . to_string( ) ,
40234065 ]
40244066 }
4067+ "quarter" | "qtr" => {
4068+ // Check that the range only covers one year
4069+ let start_date_year = start_date. year ( ) ;
4070+ if start_date_year != end_date. year ( ) {
4071+ return false ;
4072+ }
4073+
4074+ // Quarter value must be valid (1-4)
4075+ if !( 1 ..=4 ) . contains ( & value) {
4076+ return false ;
4077+ }
4078+
4079+ let quarter_start_month = ( value - 1 ) * 3 + 1 ;
4080+
4081+ // Obtain the new range
4082+ let Some ( new_start_date) =
4083+ NaiveDate :: from_ymd_opt ( start_date_year, quarter_start_month as u32 , 1 )
4084+ else {
4085+ return false ;
4086+ } ;
4087+
4088+ let Some ( new_end_date) = new_start_date
4089+ . checked_add_months ( Months :: new ( 3 ) )
4090+ . and_then ( |date| date. checked_sub_days ( Days :: new ( 1 ) ) )
4091+ else {
4092+ return false ;
4093+ } ;
4094+
4095+ // Paranoid check, If the resulting range is outside of the original range, we can't merge
4096+ // the filters
4097+ if new_start_date > end_date || new_end_date < start_date {
4098+ return false ;
4099+ }
4100+
4101+ let new_start_date = max ( new_start_date, start_date) ;
4102+ let new_end_date = min ( new_end_date, end_date) ;
4103+
4104+ vec ! [
4105+ new_start_date. format( "%Y-%m-%d" ) . to_string( ) ,
4106+ new_end_date. format( "%Y-%m-%d" ) . to_string( ) ,
4107+ ]
4108+ }
40254109 // TODO: handle more granularities
40264110 _ => return false ,
40274111 } ;
0 commit comments