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: github-unsubscr...@datafusion.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org For additional commands, e-mail: github-h...@datafusion.apache.org