mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-21 14:40:18 +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,
|
field: DateTimeField,
|
||||||
expr: Box<Expr>,
|
expr: Box<Expr>,
|
||||||
},
|
},
|
||||||
|
/// POSITION(<expr> in <expr>)
|
||||||
|
Position {
|
||||||
|
expr: Box<Expr>,
|
||||||
|
r#in: Box<Expr>,
|
||||||
|
},
|
||||||
/// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
|
/// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
|
||||||
Substring {
|
Substring {
|
||||||
expr: Box<Expr>,
|
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::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::TryCast { expr, data_type } => write!(f, "TRY_CAST({} AS {})", expr, data_type),
|
||||||
Expr::Extract { field, expr } => write!(f, "EXTRACT({} FROM {})", field, expr),
|
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::Collate { expr, collation } => write!(f, "{} COLLATE {}", expr, collation),
|
||||||
Expr::Nested(ast) => write!(f, "({})", ast),
|
Expr::Nested(ast) => write!(f, "({})", ast),
|
||||||
Expr::Value(v) => write!(f, "{}", v),
|
Expr::Value(v) => write!(f, "{}", v),
|
||||||
|
|
|
@ -423,6 +423,7 @@ impl<'a> Parser<'a> {
|
||||||
Keyword::TRY_CAST => self.parse_try_cast_expr(),
|
Keyword::TRY_CAST => self.parse_try_cast_expr(),
|
||||||
Keyword::EXISTS => self.parse_exists_expr(),
|
Keyword::EXISTS => self.parse_exists_expr(),
|
||||||
Keyword::EXTRACT => self.parse_extract_expr(),
|
Keyword::EXTRACT => self.parse_extract_expr(),
|
||||||
|
Keyword::POSITION => self.parse_position_expr(),
|
||||||
Keyword::SUBSTRING => self.parse_substring_expr(),
|
Keyword::SUBSTRING => self.parse_substring_expr(),
|
||||||
Keyword::TRIM => self.parse_trim_expr(),
|
Keyword::TRIM => self.parse_trim_expr(),
|
||||||
Keyword::INTERVAL => self.parse_literal_interval(),
|
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> {
|
pub fn parse_substring_expr(&mut self) -> Result<Expr, ParserError> {
|
||||||
// PARSE SUBSTRING (EXPR [FROM 1] [FOR 3])
|
// PARSE SUBSTRING (EXPR [FROM 1] [FOR 3])
|
||||||
self.expect_token(&Token::LParen)?;
|
self.expect_token(&Token::LParen)?;
|
||||||
|
|
|
@ -4588,3 +4588,16 @@ fn parse_time_functions() {
|
||||||
// Validating Parenthesis
|
// Validating Parenthesis
|
||||||
one_statement_parses_to("SELECT CURRENT_DATE", sql);
|
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