mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-19 13:40:15 +00:00
Support parentheses in DISTINCT clause, CURRENT_TIMESTAMP, CURRENT_TIME, and CURRENT_DATE (#391)
* Inital support in current_timestamp * Support time functions * Add Test * Fix PR * Fix tests * Add Support for distinct with parentheses * Fix nightly
This commit is contained in:
parent
ea0eb1be61
commit
fbc1d9659b
2 changed files with 92 additions and 0 deletions
|
@ -408,6 +408,9 @@ impl<'a> Parser<'a> {
|
||||||
self.prev_token();
|
self.prev_token();
|
||||||
Ok(Expr::Value(self.parse_value()?))
|
Ok(Expr::Value(self.parse_value()?))
|
||||||
}
|
}
|
||||||
|
Keyword::CURRENT_TIMESTAMP | Keyword::CURRENT_TIME | Keyword::CURRENT_DATE => {
|
||||||
|
self.parse_time_functions(ObjectName(vec![w.to_ident()]))
|
||||||
|
}
|
||||||
Keyword::CASE => self.parse_case_expr(),
|
Keyword::CASE => self.parse_case_expr(),
|
||||||
Keyword::CAST => self.parse_cast_expr(),
|
Keyword::CAST => self.parse_cast_expr(),
|
||||||
Keyword::TRY_CAST => self.parse_try_cast_expr(),
|
Keyword::TRY_CAST => self.parse_try_cast_expr(),
|
||||||
|
@ -552,6 +555,20 @@ impl<'a> Parser<'a> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_time_functions(&mut self, name: ObjectName) -> Result<Expr, ParserError> {
|
||||||
|
let args = if self.consume_token(&Token::LParen) {
|
||||||
|
self.parse_optional_args()?
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
Ok(Expr::Function(Function {
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
over: None,
|
||||||
|
distinct: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_window_frame_units(&mut self) -> Result<WindowFrameUnits, ParserError> {
|
pub fn parse_window_frame_units(&mut self) -> Result<WindowFrameUnits, ParserError> {
|
||||||
match self.next_token() {
|
match self.next_token() {
|
||||||
Token::Word(w) => match w.keyword {
|
Token::Word(w) => match w.keyword {
|
||||||
|
@ -2631,8 +2648,19 @@ impl<'a> Parser<'a> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Not Sure if Top should be cheked here as well. Trino doesn't support TOP.
|
||||||
|
let is_l_parent = if distinct {
|
||||||
|
self.consume_token(&Token::LParen)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
let projection = self.parse_comma_separated(Parser::parse_select_item)?;
|
let projection = self.parse_comma_separated(Parser::parse_select_item)?;
|
||||||
|
|
||||||
|
if is_l_parent {
|
||||||
|
self.consume_token(&Token::RParen);
|
||||||
|
}
|
||||||
|
|
||||||
// Note that for keywords to be properly handled here, they need to be
|
// Note that for keywords to be properly handled here, they need to be
|
||||||
// added to `RESERVED_FOR_COLUMN_ALIAS` / `RESERVED_FOR_TABLE_ALIAS`,
|
// added to `RESERVED_FOR_COLUMN_ALIAS` / `RESERVED_FOR_TABLE_ALIAS`,
|
||||||
// otherwise they may be parsed as an alias as part of the `projection`
|
// otherwise they may be parsed as an alias as part of the `projection`
|
||||||
|
|
|
@ -327,6 +327,22 @@ fn parse_select_distinct() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_select_distinct_two_fields() {
|
||||||
|
let sql = "SELECT DISTINCT name, id FROM customer";
|
||||||
|
let select = verified_only_select(sql);
|
||||||
|
assert!(select.distinct);
|
||||||
|
one_statement_parses_to("SELECT DISTINCT (name, id) FROM customer", sql);
|
||||||
|
assert_eq!(
|
||||||
|
&SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("name"))),
|
||||||
|
&select.projection[0]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
&SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("id"))),
|
||||||
|
&select.projection[1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_select_all() {
|
fn parse_select_all() {
|
||||||
one_statement_parses_to("SELECT ALL name FROM customer", "SELECT name FROM customer");
|
one_statement_parses_to("SELECT ALL name FROM customer", "SELECT name FROM customer");
|
||||||
|
@ -4050,3 +4066,51 @@ fn verified_only_select(query: &str) -> Select {
|
||||||
fn verified_expr(query: &str) -> Expr {
|
fn verified_expr(query: &str) -> Expr {
|
||||||
all_dialects().verified_expr(query)
|
all_dialects().verified_expr(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_time_functions() {
|
||||||
|
let sql = "SELECT CURRENT_TIMESTAMP()";
|
||||||
|
let select = verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
&Expr::Function(Function {
|
||||||
|
name: ObjectName(vec![Ident::new("CURRENT_TIMESTAMP")]),
|
||||||
|
args: vec![],
|
||||||
|
over: None,
|
||||||
|
distinct: false,
|
||||||
|
}),
|
||||||
|
expr_from_projection(&select.projection[0])
|
||||||
|
);
|
||||||
|
|
||||||
|
// Validating Parenthesis
|
||||||
|
one_statement_parses_to("SELECT CURRENT_TIMESTAMP", sql);
|
||||||
|
|
||||||
|
let sql = "SELECT CURRENT_TIME()";
|
||||||
|
let select = verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
&Expr::Function(Function {
|
||||||
|
name: ObjectName(vec![Ident::new("CURRENT_TIME")]),
|
||||||
|
args: vec![],
|
||||||
|
over: None,
|
||||||
|
distinct: false,
|
||||||
|
}),
|
||||||
|
expr_from_projection(&select.projection[0])
|
||||||
|
);
|
||||||
|
|
||||||
|
// Validating Parenthesis
|
||||||
|
one_statement_parses_to("SELECT CURRENT_TIME", sql);
|
||||||
|
|
||||||
|
let sql = "SELECT CURRENT_DATE()";
|
||||||
|
let select = verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
&Expr::Function(Function {
|
||||||
|
name: ObjectName(vec![Ident::new("CURRENT_DATE")]),
|
||||||
|
args: vec![],
|
||||||
|
over: None,
|
||||||
|
distinct: false,
|
||||||
|
}),
|
||||||
|
expr_from_projection(&select.projection[0])
|
||||||
|
);
|
||||||
|
|
||||||
|
// Validating Parenthesis
|
||||||
|
one_statement_parses_to("SELECT CURRENT_DATE", sql);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue