Skip to content

Commit

Permalink
Fix parsing of datetime functions without parenthesis (apache#930)
Browse files Browse the repository at this point in the history
  • Loading branch information
lovasoa authored and serprex committed Nov 6, 2023
1 parent 0993206 commit e0afca3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 81 deletions.
9 changes: 5 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -961,17 +961,18 @@ impl<'a> Parser<'a> {
}

pub fn parse_time_functions(&mut self, name: ObjectName) -> Result<Expr, ParserError> {
let (args, order_by) = if self.consume_token(&Token::LParen) {
self.parse_optional_args_with_orderby()?
let (args, order_by, special) = if self.consume_token(&Token::LParen) {
let (args, order_by) = self.parse_optional_args_with_orderby()?;
(args, order_by, false)
} else {
(vec![], vec![])
(vec![], vec![], true)
};
Ok(Expr::Function(Function {
name,
args,
over: None,
distinct: false,
special: false,
special,
order_by,
}))
}
Expand Down
101 changes: 24 additions & 77 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6703,90 +6703,37 @@ fn parse_offset_and_limit() {

#[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,
special: false,
order_by: vec![],
}),
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,
special: false,
order_by: vec![],
}),
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,
special: false,
order_by: vec![],
}),
expr_from_projection(&select.projection[0])
);

// Validating Parenthesis
one_statement_parses_to("SELECT CURRENT_DATE", sql);

let sql = "SELECT LOCALTIME()";
let select = verified_only_select(sql);
assert_eq!(
&Expr::Function(Function {
name: ObjectName(vec![Ident::new("LOCALTIME")]),
fn test_time_function(func_name: &'static str) {
let sql = format!("SELECT {}()", func_name);
let select = verified_only_select(&sql);
let select_localtime_func_call_ast = Function {
name: ObjectName(vec![Ident::new(func_name)]),
args: vec![],
over: None,
distinct: false,
special: false,
order_by: vec![],
}),
expr_from_projection(&select.projection[0])
);

// Validating Parenthesis
one_statement_parses_to("SELECT LOCALTIME", sql);
};
assert_eq!(
&Expr::Function(select_localtime_func_call_ast.clone()),
expr_from_projection(&select.projection[0])
);

let sql = "SELECT LOCALTIMESTAMP()";
let select = verified_only_select(sql);
assert_eq!(
&Expr::Function(Function {
name: ObjectName(vec![Ident::new("LOCALTIMESTAMP")]),
args: vec![],
over: None,
distinct: false,
special: false,
order_by: vec![],
}),
expr_from_projection(&select.projection[0])
);
// Validating Parenthesis
let sql_without_parens = format!("SELECT {}", func_name);
let mut ast_without_parens = select_localtime_func_call_ast.clone();
ast_without_parens.special = true;
assert_eq!(
&Expr::Function(ast_without_parens.clone()),
expr_from_projection(&verified_only_select(&sql_without_parens).projection[0])
);
}

// Validating Parenthesis
one_statement_parses_to("SELECT LOCALTIMESTAMP", sql);
test_time_function("CURRENT_TIMESTAMP");
test_time_function("CURRENT_TIME");
test_time_function("CURRENT_DATE");
test_time_function("LOCALTIME");
test_time_function("LOCALTIMESTAMP");
}

#[test]
Expand Down

0 comments on commit e0afca3

Please sign in to comment.