mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-20 22:20:16 +00:00
Add Support in the "Position" Function (#463)
* Add support in the position function * Add Test * Add lint fixes * Remove if * Change from to in * Remove special method for position * Fix lint * PR Review
This commit is contained in:
parent
d2487445b7
commit
8f4f01e517
3 changed files with 38 additions and 0 deletions
|
@ -291,6 +291,11 @@ pub enum Expr {
|
|||
field: DateTimeField,
|
||||
expr: Box<Expr>,
|
||||
},
|
||||
/// POSITION(<expr> in <expr>)
|
||||
Position {
|
||||
expr: Box<Expr>,
|
||||
r#in: Box<Expr>,
|
||||
},
|
||||
/// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
|
||||
Substring {
|
||||
expr: Box<Expr>,
|
||||
|
@ -438,6 +443,7 @@ impl fmt::Display for Expr {
|
|||
Expr::Cast { expr, data_type } => write!(f, "CAST({} AS {})", expr, data_type),
|
||||
Expr::TryCast { expr, data_type } => write!(f, "TRY_CAST({} AS {})", expr, data_type),
|
||||
Expr::Extract { field, expr } => write!(f, "EXTRACT({} FROM {})", field, expr),
|
||||
Expr::Position { expr, r#in } => write!(f, "POSITION({} IN {})", expr, r#in),
|
||||
Expr::Collate { expr, collation } => write!(f, "{} COLLATE {}", expr, collation),
|
||||
Expr::Nested(ast) => write!(f, "({})", ast),
|
||||
Expr::Value(v) => write!(f, "{}", v),
|
||||
|
|
|
@ -423,6 +423,7 @@ impl<'a> Parser<'a> {
|
|||
Keyword::TRY_CAST => self.parse_try_cast_expr(),
|
||||
Keyword::EXISTS => self.parse_exists_expr(),
|
||||
Keyword::EXTRACT => self.parse_extract_expr(),
|
||||
Keyword::POSITION => self.parse_position_expr(),
|
||||
Keyword::SUBSTRING => self.parse_substring_expr(),
|
||||
Keyword::TRIM => self.parse_trim_expr(),
|
||||
Keyword::INTERVAL => self.parse_literal_interval(),
|
||||
|
@ -779,6 +780,24 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn parse_position_expr(&mut self) -> Result<Expr, ParserError> {
|
||||
// PARSE SELECT POSITION('@' in field)
|
||||
self.expect_token(&Token::LParen)?;
|
||||
|
||||
// Parse the subexpr till the IN keyword
|
||||
let expr = self.parse_subexpr(Self::BETWEEN_PREC)?;
|
||||
if self.parse_keyword(Keyword::IN) {
|
||||
let from = self.parse_expr()?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
Ok(Expr::Position {
|
||||
expr: Box::new(expr),
|
||||
r#in: Box::new(from),
|
||||
})
|
||||
} else {
|
||||
return parser_err!("Position function must include IN keyword".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_substring_expr(&mut self) -> Result<Expr, ParserError> {
|
||||
// PARSE SUBSTRING (EXPR [FROM 1] [FOR 3])
|
||||
self.expect_token(&Token::LParen)?;
|
||||
|
|
|
@ -4588,3 +4588,16 @@ fn parse_time_functions() {
|
|||
// Validating Parenthesis
|
||||
one_statement_parses_to("SELECT CURRENT_DATE", sql);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_position() {
|
||||
let sql = "SELECT POSITION('@' IN field)";
|
||||
let select = verified_only_select(sql);
|
||||
assert_eq!(
|
||||
&Expr::Position {
|
||||
expr: Box::new(Expr::Value(Value::SingleQuotedString("@".to_string()))),
|
||||
r#in: Box::new(Expr::Identifier(Ident::new("field"))),
|
||||
},
|
||||
expr_from_projection(only(&select.projection))
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue