Skip to content

Commit ecdee10

Browse files
committed
SGA-3801 Simplified concat logic, refactor names, moved test to common
1 parent 059aab1 commit ecdee10

File tree

5 files changed

+27
-49
lines changed

5 files changed

+27
-49
lines changed

src/dialect/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ pub trait Dialect: Debug + Any {
478478

479479
// Does the Dialect support concatenating of string literal
480480
// Example: SELECT 'Hello ' "world" => SELECT 'Hello world'
481-
fn supports_concat_quoted_identifiers(&self) -> bool {
481+
fn supports_string_literal_concatenation(&self) -> bool {
482482
false
483483
}
484484

src/dialect/mysql.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ impl Dialect for MySqlDialect {
7171
true
7272
}
7373

74-
// 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>
75-
fn supports_concat_quoted_identifiers(&self) -> bool {
74+
/// see <https://dev.mysql.com/doc/refman/8.4/en/string-functions.html#function_concat>
75+
fn supports_string_literal_concatenation(&self) -> bool {
7676
true
7777
}
7878

src/parser/mod.rs

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9808,18 +9808,12 @@ impl<'a> Parser<'a> {
98089808
// bigdecimal feature is enabled, and is otherwise a no-op
98099809
// (i.e., it returns the input string).
98109810
Token::Number(n, l) => ok_value(Value::Number(Self::parse(n, span.start)?, l)),
9811-
Token::SingleQuotedString(ref s) => {
9812-
if self.dialect.supports_concat_quoted_identifiers() {
9813-
return ok_value(Value::SingleQuotedString(self.combine_quoted(next_token)));
9814-
}
9815-
ok_value(Value::SingleQuotedString(s.to_string()))
9816-
}
9817-
Token::DoubleQuotedString(ref s) => {
9818-
if self.dialect.supports_concat_quoted_identifiers() {
9819-
return ok_value(Value::DoubleQuotedString(self.combine_quoted(next_token)));
9820-
}
9821-
ok_value(Value::DoubleQuotedString(s.to_string()))
9822-
}
9811+
Token::SingleQuotedString(ref s) => ok_value(Value::SingleQuotedString(
9812+
self.maybe_concat_string_literal(s.to_string()),
9813+
)),
9814+
Token::DoubleQuotedString(ref s) => ok_value(Value::DoubleQuotedString(
9815+
self.maybe_concat_string_literal(s.to_string()),
9816+
)),
98239817
Token::TripleSingleQuotedString(ref s) => {
98249818
ok_value(Value::TripleSingleQuotedString(s.to_string()))
98259819
}
@@ -9889,33 +9883,16 @@ impl<'a> Parser<'a> {
98899883
}
98909884
}
98919885

9892-
fn is_quoted_string(&self, token: &Token) -> bool {
9893-
matches!(
9894-
token,
9895-
Token::SingleQuotedString(_) | Token::DoubleQuotedString(_)
9896-
)
9897-
}
9898-
9899-
fn get_quoted_string(&self, token: &Token) -> String {
9900-
match token {
9901-
Token::SingleQuotedString(s) => s.clone(),
9902-
Token::DoubleQuotedString(s) => s.clone(),
9903-
_ => String::new(),
9904-
}
9905-
}
9906-
9907-
fn combine_quoted(&mut self, token: TokenWithSpan) -> String {
9908-
let mut combined_string = self.get_quoted_string(&token.token);
9909-
loop {
9910-
let next_token = self.next_token();
9911-
if !self.is_quoted_string(&next_token.token) {
9912-
self.prev_token();
9913-
break;
9886+
fn maybe_concat_string_literal(&mut self, mut str: String) -> String {
9887+
if self.dialect.supports_string_literal_concatenation() {
9888+
while let Token::SingleQuotedString(ref s) | Token::DoubleQuotedString(ref s) =
9889+
self.peek_token_ref().token
9890+
{
9891+
str.push_str(s.clone().as_str());
9892+
self.advance_token();
99149893
}
9915-
let s = self.get_quoted_string(&next_token.token);
9916-
combined_string.push_str(&s);
99179894
}
9918-
combined_string
9895+
str
99199896
}
99209897

99219898
/// Parse an unsigned numeric literal

tests/sqlparser_common.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17027,3 +17027,13 @@ fn test_parse_semantic_view_table_factor() {
1702717027
_ => panic!("Expected Query statement"),
1702817028
}
1702917029
}
17030+
17031+
#[test]
17032+
fn parse_adjacent_string_literal_concatenation() {
17033+
let sql = r#"SELECT 'M' "y" 'S' "q" 'l'"#;
17034+
let dialects = all_dialects_where(|d| d.supports_string_literal_concatenation());
17035+
dialects.one_statement_parses_to(sql, r"SELECT 'MySql'");
17036+
17037+
let sql = "SELECT * FROM t WHERE col = 'Hello' \n ' ' \t 'World!'";
17038+
dialects.one_statement_parses_to(sql, r"SELECT * FROM t WHERE col = 'Hello World!'");
17039+
}

tests/sqlparser_mysql.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4247,12 +4247,3 @@ fn test_create_index_options() {
42474247
"CREATE INDEX idx_name ON t(c1, c2) USING BTREE LOCK = EXCLUSIVE ALGORITHM = DEFAULT",
42484248
);
42494249
}
4250-
4251-
#[test]
4252-
fn parse_adjacent_string_literal_concatenation() {
4253-
let sql = r#"SELECT 'M' "y" 'S' "q" 'l'"#;
4254-
mysql().one_statement_parses_to(sql, r"SELECT 'MySql'");
4255-
4256-
let sql = "SELECT * FROM t WHERE col = 'Hello' \n ' ' \t 'World!'";
4257-
mysql().one_statement_parses_to(sql, r"SELECT * FROM t WHERE col = 'Hello World!'");
4258-
}

0 commit comments

Comments
 (0)