iffyio commented on code in PR #2003:
URL:
https://github.com/apache/datafusion-sqlparser-rs/pull/2003#discussion_r2287832355
##########
src/dialect/mod.rs:
##########
@@ -476,6 +476,12 @@ pub trait Dialect: Debug + Any {
false
}
+ // Does the Dialect support concatenating of string literal
+ // Example: SELECT 'Hello ' "world" => SELECT 'Hello world'
+ fn supports_concat_quoted_identifiers(&self) -> bool {
Review Comment:
```suggestion
/// Does the Dialect support concatenating of string literal
/// Example: `SELECT 'Hello ' "world" => 'Hello world'`
fn supports_string_literal_concatenation(&self) -> bool {
```
##########
src/dialect/mysql.rs:
##########
@@ -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>
Review Comment:
```suggestion
/// see
<https://dev.mysql.com/doc/refman/8.4/en/string-functions.html#function_concat>
```
##########
tests/sqlparser_mysql.rs:
##########
@@ -4245,3 +4245,12 @@ fn test_create_index_options() {
"CREATE INDEX idx_name ON t(c1, c2) USING BTREE LOCK = EXCLUSIVE
ALGORITHM = DEFAULT",
);
}
+
+#[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'");
Review Comment:
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
##########
src/parser/mod.rs:
##########
@@ -9755,6 +9765,35 @@ impl<'a> Parser<'a> {
}
}
+ 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
+ }
+
Review Comment:
Can we simplify with something roughly like the following?
```rust
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.
```rust
Token::SingleQuotedString(ref s) =>
self.maybe_concat_string_literal(s.to_string(), Value::SingleQuotedString)
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]