Support named arguments in function invocations (#250)

This commit supports functions with argument names.

the format is :
"Select some_function( a => exp, b => exp2 .. ) FROM table1
OR
"select * from table(function(a => exp)) f;"

see:
https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#named-argument-assignment-token
or the motivating example from snowflake:
https://docs.snowflake.com/en/sql-reference/functions/flatten.html
This commit is contained in:
eyalleshem 2020-08-02 08:04:55 +03:00 committed by GitHub
parent 580e4b1d64
commit 1cc3bf4099
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 10 deletions

View file

@ -99,6 +99,8 @@ pub enum Token {
LBrace,
/// Right brace `}`
RBrace,
/// Right Arrow `=>`
RArrow,
}
impl fmt::Display for Token {
@ -139,6 +141,7 @@ impl fmt::Display for Token {
Token::Pipe => f.write_str("|"),
Token::LBrace => f.write_str("{"),
Token::RBrace => f.write_str("}"),
Token::RArrow => f.write_str("=>"),
}
}
}
@ -400,7 +403,13 @@ impl<'a> Tokenizer<'a> {
_ => Ok(Some(Token::Pipe)),
}
}
'=' => self.consume_and_return(chars, Token::Eq),
'=' => {
chars.next(); // consume
match chars.peek() {
Some('>') => self.consume_and_return(chars, Token::RArrow),
_ => Ok(Some(Token::Eq)),
}
}
'.' => self.consume_and_return(chars, Token::Period),
'!' => {
chars.next(); // consume
@ -766,6 +775,23 @@ mod tests {
compare(expected, tokens);
}
#[test]
fn tokenize_right_arrow() {
let sql = String::from("FUNCTION(key=>value)");
let dialect = GenericDialect {};
let mut tokenizer = Tokenizer::new(&dialect, &sql);
let tokens = tokenizer.tokenize().unwrap();
let expected = vec![
Token::make_word("FUNCTION", None),
Token::LParen,
Token::make_word("key", None),
Token::RArrow,
Token::make_word("value", None),
Token::RParen,
];
compare(expected, tokens);
}
#[test]
fn tokenize_is_null() {
let sql = String::from("a IS NULL");