Skip to content

Commit daf8c33

Browse files
committed
feat: support within filter
1 parent 71dd860 commit daf8c33

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

src/parser/mod.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,7 @@ impl<'a> Parser<'a> {
918918
let mut expr = self.parse_prefix()?;
919919
debug!("prefix: {:?}", expr);
920920
loop {
921+
expr = self.parse_within_filter(expr)?;
921922
expr = self.parse_range_expr(expr)?;
922923
let next_precedence = self.get_next_precedence()?;
923924
debug!("next precedence: {:?}", next_precedence);
@@ -931,6 +932,33 @@ impl<'a> Parser<'a> {
931932
Ok(expr)
932933
}
933934

935+
/// Parse within syntax like `select * from monitor where ts within '2025-01'`
936+
fn parse_within_filter(&mut self, expr: Expr) -> Result<Expr, ParserError> {
937+
if !self.parse_keyword(Keyword::WITHIN) {
938+
return Ok(expr);
939+
}
940+
let Expr::Identifier(ident) = expr else {
941+
return Ok(expr);
942+
};
943+
let value = self.parse_value()?;
944+
Ok(Expr::Function(Function {
945+
name: ObjectName(vec![Ident::new("within_filter")]),
946+
args: FunctionArguments::List(FunctionArgumentList {
947+
duplicate_treatment: None,
948+
args: vec![
949+
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Identifier(ident))),
950+
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(value))),
951+
],
952+
clauses: vec![],
953+
}),
954+
filter: None,
955+
null_treatment: None,
956+
over: None,
957+
parameters: FunctionArguments::None,
958+
within_group: vec![],
959+
}))
960+
}
961+
934962
/// Parse Range clause with format `RANGE [ Duration literal | (INTERVAL [interval expr]) ] FILL [ NULL | PREV .....]`
935963
fn parse_range_expr(&mut self, expr: Expr) -> Result<Expr, ParserError> {
936964
let index = self.index;
@@ -13433,4 +13461,83 @@ mod tests {
1343313461

1343413462
assert!(Parser::parse_sql(&MySqlDialect {}, sql).is_err());
1343513463
}
13464+
13465+
#[test]
13466+
fn test_within_filter() {
13467+
// args: FunctionArguments::List(FunctionArgumentList { duplicate_treatment: None, args: vec![ FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Identifier(ident))),
13468+
//FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(value))),], clauses: vec![] }),
13469+
13470+
let sql = "select * from monitors where ts within '2024';";
13471+
let mut parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
13472+
let result = parser.parse_query().unwrap();
13473+
if let SetExpr::Select(select) = result.body.as_ref() {
13474+
let expected = &select.selection;
13475+
assert_eq!(
13476+
expected,
13477+
&Some(Expr::Function(Function {
13478+
name: ObjectName(vec![Ident::new("within_filter")]),
13479+
args: FunctionArguments::List(FunctionArgumentList {
13480+
duplicate_treatment: None,
13481+
args: vec![
13482+
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Identifier(
13483+
Ident::new("ts")
13484+
))),
13485+
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
13486+
Value::SingleQuotedString("2024".to_string())
13487+
)))
13488+
],
13489+
clauses: vec![]
13490+
}),
13491+
filter: None,
13492+
null_treatment: None,
13493+
over: None,
13494+
parameters: FunctionArguments::None,
13495+
within_group: vec![],
13496+
}))
13497+
);
13498+
} else {
13499+
unreachable!();
13500+
}
13501+
let sql = "select * from monitors where ts within '1915' and memory < 1024;";
13502+
let mut parser = Parser::new(&GenericDialect {}).try_with_sql(sql).unwrap();
13503+
let result = parser.parse_query().unwrap();
13504+
if let SetExpr::Select(select) = result.body.as_ref() {
13505+
let expected = &select.selection;
13506+
let within_expr = Expr::Function(Function {
13507+
name: ObjectName(vec![Ident::new("within_filter")]),
13508+
args: FunctionArguments::List(FunctionArgumentList {
13509+
duplicate_treatment: None,
13510+
args: vec![
13511+
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Identifier(Ident::new(
13512+
"ts",
13513+
)))),
13514+
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
13515+
Value::SingleQuotedString("1915".to_string()),
13516+
))),
13517+
],
13518+
clauses: vec![],
13519+
}),
13520+
filter: None,
13521+
null_treatment: None,
13522+
over: None,
13523+
parameters: FunctionArguments::None,
13524+
within_group: vec![],
13525+
});
13526+
let right = Expr::BinaryOp {
13527+
left: Box::new(Expr::Identifier(Ident::new("memory"))),
13528+
op: BinaryOperator::Lt,
13529+
right: Box::new(Expr::Value(Value::Number("1024".to_string(), false))),
13530+
};
13531+
assert_eq!(
13532+
expected,
13533+
&Some(Expr::BinaryOp {
13534+
left: Box::new(within_expr),
13535+
op: BinaryOperator::And,
13536+
right: Box::new(right)
13537+
})
13538+
);
13539+
} else {
13540+
unreachable!();
13541+
}
13542+
}
1343613543
}

0 commit comments

Comments
 (0)