Skip to content

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

etgarperets
Copy link
Contributor

… space in mySQL

@@ -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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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>

Comment on lines +479 to +481
// Does the Dialect support concatenating of string literal
// Example: SELECT 'Hello ' "world" => SELECT 'Hello world'
fn supports_concat_quoted_identifiers(&self) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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 {

Comment on lines +9768 to +9796
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
}

Copy link
Contributor

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'");
Copy link
Contributor

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

@iffyio iffyio changed the title SGA-3801 Added support for concatenating string literals saperated by… Added support for string literal concatenation Aug 20, 2025
@iffyio iffyio changed the title Added support for string literal concatenation Add support for string literal concatenation Aug 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants