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:
yuval-illumex 2022-02-05 13:39:35 +02:00 committed by GitHub
parent ea0eb1be61
commit fbc1d9659b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 0 deletions

View file

@ -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`

View file

@ -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);
}