@@ -867,6 +867,7 @@ impl<'a> Parser<'a> {
867867 let mut expr = self . parse_prefix ( ) ?;
868868 debug ! ( "prefix: {:?}" , expr) ;
869869 loop {
870+ expr = self . parse_within_filter ( expr) ?;
870871 expr = self . parse_range_expr ( expr) ?;
871872 let next_precedence = self . get_next_precedence ( ) ?;
872873 debug ! ( "next precedence: {:?}" , next_precedence) ;
@@ -880,6 +881,30 @@ impl<'a> Parser<'a> {
880881 Ok ( expr)
881882 }
882883
884+ /// Parse within syntax like `select * from monitor where ts within '2025-01'`
885+ fn parse_within_filter ( & mut self , expr : Expr ) -> Result < Expr , ParserError > {
886+ if !self . parse_keyword ( Keyword :: WITHIN ) {
887+ return Ok ( expr) ;
888+ }
889+ let Expr :: Identifier ( ident) = expr else {
890+ return Ok ( expr) ;
891+ } ;
892+ let value = self . parse_value ( ) ?;
893+ Ok ( Expr :: Function ( Function {
894+ name : ObjectName ( vec ! [ Ident :: new( "within_filter" ) ] ) ,
895+ args : vec ! [
896+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( Expr :: Identifier ( ident) ) ) ,
897+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( Expr :: Value ( value) ) ) ,
898+ ] ,
899+ filter : None ,
900+ null_treatment : None ,
901+ over : None ,
902+ distinct : false ,
903+ special : false ,
904+ order_by : vec ! [ ] ,
905+ } ) )
906+ }
907+
883908 /// Parse Range clause with format `RANGE [ Duration literal | (INTERVAL [interval expr]) ] FILL [ NULL | PREV .....]`
884909 fn parse_range_expr ( & mut self , expr : Expr ) -> Result < Expr , ParserError > {
885910 let index = self . index ;
@@ -10965,4 +10990,72 @@ mod tests {
1096510990
1096610991 assert ! ( Parser :: parse_sql( & MySqlDialect { } , sql) . is_err( ) ) ;
1096710992 }
10993+
10994+ #[ test]
10995+ fn test_within_filter ( ) {
10996+ let sql = "select * from monitors where ts within '2024';" ;
10997+ let mut parser = Parser :: new ( & GenericDialect { } ) . try_with_sql ( sql) . unwrap ( ) ;
10998+ let result = parser. parse_query ( ) . unwrap ( ) ;
10999+ if let SetExpr :: Select ( select) = result. body . as_ref ( ) {
11000+ let expected = & select. selection ;
11001+ assert_eq ! (
11002+ expected,
11003+ & Some ( Expr :: Function ( Function {
11004+ name: ObjectName ( vec![ Ident :: new( "within_filter" ) ] ) ,
11005+ args: vec![
11006+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( Expr :: Identifier ( Ident :: new(
11007+ "ts"
11008+ ) ) ) ) ,
11009+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( Expr :: Value (
11010+ Value :: SingleQuotedString ( "2024" . to_string( ) )
11011+ ) ) )
11012+ ] ,
11013+ filter: None ,
11014+ null_treatment: None ,
11015+ over: None ,
11016+ distinct: false ,
11017+ special: false ,
11018+ order_by: vec![ ]
11019+ } ) )
11020+ ) ;
11021+ } else {
11022+ unreachable ! ( ) ;
11023+ }
11024+ let sql = "select * from monitors where ts within '1915' and memory < 1024;" ;
11025+ let mut parser = Parser :: new ( & GenericDialect { } ) . try_with_sql ( sql) . unwrap ( ) ;
11026+ let result = parser. parse_query ( ) . unwrap ( ) ;
11027+ if let SetExpr :: Select ( select) = result. body . as_ref ( ) {
11028+ let expected = & select. selection ;
11029+ let within_expr = Expr :: Function ( Function {
11030+ name : ObjectName ( vec ! [ Ident :: new( "within_filter" ) ] ) ,
11031+ args : vec ! [
11032+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( Expr :: Identifier ( Ident :: new( "ts" ) ) ) ) ,
11033+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( Expr :: Value (
11034+ Value :: SingleQuotedString ( "1915" . to_string( ) ) ,
11035+ ) ) ) ,
11036+ ] ,
11037+ filter : None ,
11038+ null_treatment : None ,
11039+ over : None ,
11040+ distinct : false ,
11041+ special : false ,
11042+ order_by : vec ! [ ] ,
11043+ } ) ;
11044+ let right = Expr :: BinaryOp {
11045+ left : Box :: new ( Expr :: Identifier ( Ident :: new ( "memory" ) ) ) ,
11046+ op : BinaryOperator :: Lt ,
11047+ right : Box :: new ( Expr :: Value ( Value :: Number ( "1024" . to_string ( ) , false ) ) ) ,
11048+ } ;
11049+ assert_eq ! (
11050+ expected,
11051+ & Some ( Expr :: BinaryOp {
11052+ left: Box :: new( within_expr) ,
11053+ op: BinaryOperator :: And ,
11054+ right: Box :: new( right)
11055+ } )
11056+ ) ;
11057+ } else {
11058+ unreachable ! ( ) ;
11059+ }
11060+ }
1096811061}
0 commit comments