-
Notifications
You must be signed in to change notification settings - Fork 632
Add support for string literal concatenation #2003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add support for string literal concatenation #2003
Conversation
@@ -71,6 +71,11 @@ impl Dialect for MySqlDialect { | |||
true | |||
} | |||
|
|||
// see <https://dev.mysql.com/doc/refman/8.4/en/string-functions.html#:~:text=mysql%3E%20SELECT%20%27My%27%20%27S%27%20%27QL%27%3B%0A%20%20%20%20%20%20%20%20%2D%3E%20%27MySQL%27> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// see <https://dev.mysql.com/doc/refman/8.4/en/string-functions.html#:~:text=mysql%3E%20SELECT%20%27My%27%20%27S%27%20%27QL%27%3B%0A%20%20%20%20%20%20%20%20%2D%3E%20%27MySQL%27> | |
/// see <https://dev.mysql.com/doc/refman/8.4/en/string-functions.html#function_concat> |
// Does the Dialect support concatenating of string literal | ||
// Example: SELECT 'Hello ' "world" => SELECT 'Hello world' | ||
fn supports_concat_quoted_identifiers(&self) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Does the Dialect support concatenating of string literal | |
// Example: SELECT 'Hello ' "world" => SELECT 'Hello world' | |
fn supports_concat_quoted_identifiers(&self) -> bool { | |
/// Does the Dialect support concatenating of string literal | |
/// Example: `SELECT 'Hello ' "world" => 'Hello world'` | |
fn supports_string_literal_concatenation(&self) -> bool { |
fn is_quoted_string(&self, token: &Token) -> bool { | ||
matches!( | ||
token, | ||
Token::SingleQuotedString(_) | Token::DoubleQuotedString(_) | ||
) | ||
} | ||
|
||
fn get_quoted_string(&self, token: &Token) -> String { | ||
match token { | ||
Token::SingleQuotedString(s) => s.clone(), | ||
Token::DoubleQuotedString(s) => s.clone(), | ||
_ => String::new(), | ||
} | ||
} | ||
|
||
fn combine_quoted(&mut self, token: TokenWithSpan) -> String { | ||
let mut combined_string = self.get_quoted_string(&token.token); | ||
loop { | ||
let next_token = self.next_token(); | ||
if !self.is_quoted_string(&next_token.token) { | ||
self.prev_token(); | ||
break; | ||
} | ||
let s = self.get_quoted_string(&next_token.token); | ||
combined_string.push_str(&s); | ||
} | ||
combined_string | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we simplify with something roughly like the following?
fn maybe_concat_string_literal<F: FnOnce(String) -> Value>(
mut str: String,
value_fn: F
) -> Result<Value> {
if self.dialect.supports_concat_quoted_identifiers() {
loop {
match self.peek_token_ref() {
Token::SingleQuotedString(s) | Token::DoubleQuotedString(s) => {
self.advance_token();
str.append(s);
}
_ => {
break
}
}
}
}
Ok(value_fn(str))
}
And the caller only does e.g.
Token::SingleQuotedString(ref s) => self.maybe_concat_string_literal(s.to_string(), Value::SingleQuotedString)
#[test] | ||
fn parse_adjacent_string_literal_concatenation() { | ||
let sql = r#"SELECT 'M' "y" 'S' "q" 'l'"#; | ||
mysql().one_statement_parses_to(sql, r"SELECT 'MySql'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is gated by a dialect flag can we use all_dialects_where(|d| d.supports...)
so that new dialects are covered by tests when enabled
… space in mySQL