mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Parse SUBSTR
as alias for SUBSTRING
(#1769)
This commit is contained in:
parent
f487cbe004
commit
939fbdd4f6
7 changed files with 32 additions and 4 deletions
|
@ -890,6 +890,10 @@ pub enum Expr {
|
|||
/// true if the expression is represented using the `SUBSTRING(expr, start, len)` syntax
|
||||
/// This flag is used for formatting.
|
||||
special: bool,
|
||||
|
||||
/// true if the expression is represented using the `SUBSTR` shorthand
|
||||
/// This flag is used for formatting.
|
||||
shorthand: bool,
|
||||
},
|
||||
/// ```sql
|
||||
/// TRIM([BOTH | LEADING | TRAILING] [<expr> FROM] <expr>)
|
||||
|
@ -1719,8 +1723,13 @@ impl fmt::Display for Expr {
|
|||
substring_from,
|
||||
substring_for,
|
||||
special,
|
||||
shorthand,
|
||||
} => {
|
||||
write!(f, "SUBSTRING({expr}")?;
|
||||
f.write_str("SUBSTR")?;
|
||||
if !*shorthand {
|
||||
f.write_str("ING")?;
|
||||
}
|
||||
write!(f, "({expr}")?;
|
||||
if let Some(from_part) = substring_from {
|
||||
if *special {
|
||||
write!(f, ", {from_part}")?;
|
||||
|
|
|
@ -1503,6 +1503,7 @@ impl Spanned for Expr {
|
|||
substring_from,
|
||||
substring_for,
|
||||
special: _,
|
||||
shorthand: _,
|
||||
} => union_spans(
|
||||
core::iter::once(expr.span())
|
||||
.chain(substring_from.as_ref().map(|i| i.span()))
|
||||
|
|
|
@ -841,6 +841,7 @@ define_keywords!(
|
|||
STRING,
|
||||
STRUCT,
|
||||
SUBMULTISET,
|
||||
SUBSTR,
|
||||
SUBSTRING,
|
||||
SUBSTRING_REGEX,
|
||||
SUCCEEDS,
|
||||
|
|
|
@ -1302,7 +1302,10 @@ impl<'a> Parser<'a> {
|
|||
Keyword::POSITION if self.peek_token_ref().token == Token::LParen => {
|
||||
Ok(Some(self.parse_position_expr(w.clone().into_ident(w_span))?))
|
||||
}
|
||||
Keyword::SUBSTRING => Ok(Some(self.parse_substring_expr()?)),
|
||||
Keyword::SUBSTR | Keyword::SUBSTRING => {
|
||||
self.prev_token();
|
||||
Ok(Some(self.parse_substring()?))
|
||||
}
|
||||
Keyword::OVERLAY => Ok(Some(self.parse_overlay_expr()?)),
|
||||
Keyword::TRIM => Ok(Some(self.parse_trim_expr()?)),
|
||||
Keyword::INTERVAL => Ok(Some(self.parse_interval()?)),
|
||||
|
@ -2412,8 +2415,16 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_substring_expr(&mut self) -> Result<Expr, ParserError> {
|
||||
// PARSE SUBSTRING (EXPR [FROM 1] [FOR 3])
|
||||
// { SUBSTRING | SUBSTR } (<EXPR> [FROM 1] [FOR 3])
|
||||
pub fn parse_substring(&mut self) -> Result<Expr, ParserError> {
|
||||
let shorthand = match self.expect_one_of_keywords(&[Keyword::SUBSTR, Keyword::SUBSTRING])? {
|
||||
Keyword::SUBSTR => true,
|
||||
Keyword::SUBSTRING => false,
|
||||
_ => {
|
||||
self.prev_token();
|
||||
return self.expected("SUBSTR or SUBSTRING", self.peek_token());
|
||||
}
|
||||
};
|
||||
self.expect_token(&Token::LParen)?;
|
||||
let expr = self.parse_expr()?;
|
||||
let mut from_expr = None;
|
||||
|
@ -2433,6 +2444,7 @@ impl<'a> Parser<'a> {
|
|||
substring_from: from_expr.map(Box::new),
|
||||
substring_for: to_expr.map(Box::new),
|
||||
special,
|
||||
shorthand,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -7607,6 +7607,9 @@ fn parse_substring() {
|
|||
verified_stmt("SELECT SUBSTRING('1', 1, 3)");
|
||||
verified_stmt("SELECT SUBSTRING('1', 1)");
|
||||
verified_stmt("SELECT SUBSTRING('1' FOR 3)");
|
||||
verified_stmt("SELECT SUBSTRING('foo' FROM 1 FOR 2) FROM t");
|
||||
verified_stmt("SELECT SUBSTR('foo' FROM 1 FOR 2) FROM t");
|
||||
verified_stmt("SELECT SUBSTR('foo', 1, 2) FROM t");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1133,6 +1133,7 @@ fn parse_substring_in_select() {
|
|||
(number("1")).with_empty_span()
|
||||
))),
|
||||
special: true,
|
||||
shorthand: false,
|
||||
})],
|
||||
into: None,
|
||||
from: vec![TableWithJoins {
|
||||
|
|
|
@ -2590,6 +2590,7 @@ fn parse_substring_in_select() {
|
|||
(number("1")).with_empty_span()
|
||||
))),
|
||||
special: true,
|
||||
shorthand: false,
|
||||
})],
|
||||
into: None,
|
||||
from: vec![TableWithJoins {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue