mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-23 07:24:10 +00:00
Add TrimWhereField for parse_trim_expr
(#334)
* Remove Box from `trim_where` * Add TrimWhereField for `parse_trim_expr` * Add negative test case
This commit is contained in:
parent
5ce67177b3
commit
af1ac865b1
4 changed files with 41 additions and 5 deletions
|
@ -40,7 +40,7 @@ pub use self::query::{
|
||||||
Query, Select, SelectItem, SetExpr, SetOperator, TableAlias, TableFactor, TableWithJoins, Top,
|
Query, Select, SelectItem, SetExpr, SetOperator, TableAlias, TableFactor, TableWithJoins, Top,
|
||||||
Values, With,
|
Values, With,
|
||||||
};
|
};
|
||||||
pub use self::value::{DateTimeField, Value};
|
pub use self::value::{DateTimeField, TrimWhereField, Value};
|
||||||
|
|
||||||
struct DisplaySeparated<'a, T>
|
struct DisplaySeparated<'a, T>
|
||||||
where
|
where
|
||||||
|
@ -231,7 +231,7 @@ pub enum Expr {
|
||||||
Trim {
|
Trim {
|
||||||
expr: Box<Expr>,
|
expr: Box<Expr>,
|
||||||
// ([BOTH | LEADING | TRAILING], <expr>)
|
// ([BOTH | LEADING | TRAILING], <expr>)
|
||||||
trim_where: Option<(Box<Ident>, Box<Expr>)>,
|
trim_where: Option<(TrimWhereField, Box<Expr>)>,
|
||||||
},
|
},
|
||||||
/// `expr COLLATE collation`
|
/// `expr COLLATE collation`
|
||||||
Collate {
|
Collate {
|
||||||
|
|
|
@ -157,3 +157,22 @@ impl<'a> fmt::Display for EscapeSingleQuoteString<'a> {
|
||||||
pub fn escape_single_quote_string(s: &str) -> EscapeSingleQuoteString<'_> {
|
pub fn escape_single_quote_string(s: &str) -> EscapeSingleQuoteString<'_> {
|
||||||
EscapeSingleQuoteString(s)
|
EscapeSingleQuoteString(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub enum TrimWhereField {
|
||||||
|
Both,
|
||||||
|
Leading,
|
||||||
|
Trailing,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for TrimWhereField {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use TrimWhereField::*;
|
||||||
|
f.write_str(match self {
|
||||||
|
Both => "BOTH",
|
||||||
|
Leading => "LEADING",
|
||||||
|
Trailing => "TRAILING",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -666,10 +666,10 @@ impl<'a> Parser<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.any(|d| word.keyword == *d)
|
.any(|d| word.keyword == *d)
|
||||||
{
|
{
|
||||||
let ident = self.parse_identifier()?;
|
let trim_where = self.parse_trim_where()?;
|
||||||
let sub_expr = self.parse_expr()?;
|
let sub_expr = self.parse_expr()?;
|
||||||
self.expect_keyword(Keyword::FROM)?;
|
self.expect_keyword(Keyword::FROM)?;
|
||||||
where_expr = Some((ident, sub_expr))
|
where_expr = Some((trim_where, Box::new(sub_expr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let expr = self.parse_expr()?;
|
let expr = self.parse_expr()?;
|
||||||
|
@ -677,10 +677,22 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
Ok(Expr::Trim {
|
Ok(Expr::Trim {
|
||||||
expr: Box::new(expr),
|
expr: Box::new(expr),
|
||||||
trim_where: where_expr.map(|(ident, expr)| (Box::new(ident), Box::new(expr))),
|
trim_where: where_expr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_trim_where(&mut self) -> Result<TrimWhereField, ParserError> {
|
||||||
|
match self.next_token() {
|
||||||
|
Token::Word(w) => match w.keyword {
|
||||||
|
Keyword::BOTH => Ok(TrimWhereField::Both),
|
||||||
|
Keyword::LEADING => Ok(TrimWhereField::Leading),
|
||||||
|
Keyword::TRAILING => Ok(TrimWhereField::Trailing),
|
||||||
|
_ => self.expected("trim_where field", Token::Word(w))?,
|
||||||
|
},
|
||||||
|
unexpected => self.expected("trim_where field", unexpected),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a SQL LISTAGG expression, e.g. `LISTAGG(...) WITHIN GROUP (ORDER BY ...)`.
|
/// Parse a SQL LISTAGG expression, e.g. `LISTAGG(...) WITHIN GROUP (ORDER BY ...)`.
|
||||||
pub fn parse_listagg_expr(&mut self) -> Result<Expr, ParserError> {
|
pub fn parse_listagg_expr(&mut self) -> Result<Expr, ParserError> {
|
||||||
self.expect_token(&Token::LParen)?;
|
self.expect_token(&Token::LParen)?;
|
||||||
|
|
|
@ -2765,6 +2765,11 @@ fn parse_trim() {
|
||||||
);
|
);
|
||||||
|
|
||||||
one_statement_parses_to("SELECT TRIM(' foo ')", "SELECT TRIM(' foo ')");
|
one_statement_parses_to("SELECT TRIM(' foo ')", "SELECT TRIM(' foo ')");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected ), found: 'xyz'".to_owned()),
|
||||||
|
parse_sql_statements("SELECT TRIM(FOO 'xyz' FROM 'xyzfooxyz')").unwrap_err()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue