Skip to content

Commit 62cf16f

Browse files
authored
Redshift: Support implicit string concatenation using newline (#2167)
1 parent be460b2 commit 62cf16f

File tree

4 files changed

+63
-0
lines changed

4 files changed

+63
-0
lines changed

src/dialect/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,19 @@ pub trait Dialect: Debug + Any {
489489
false
490490
}
491491

492+
/// Returns true if the dialect supports concatenating string literals with a newline.
493+
/// For example, the following statement would return `true`:
494+
/// ```sql
495+
/// SELECT 'abc' in (
496+
/// 'a'
497+
/// 'b'
498+
/// 'c'
499+
/// );
500+
/// ```
501+
fn supports_string_literal_concatenation_with_newline(&self) -> bool {
502+
false
503+
}
504+
492505
/// Does the dialect support trailing commas in the projection list?
493506
fn supports_projection_trailing_commas(&self) -> bool {
494507
self.supports_trailing_commas()

src/dialect/redshift.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,8 @@ impl Dialect for RedshiftSqlDialect {
147147
fn supports_create_table_like_parenthesized(&self) -> bool {
148148
true
149149
}
150+
151+
fn supports_string_literal_concatenation_with_newline(&self) -> bool {
152+
true
153+
}
150154
}

src/parser/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11325,7 +11325,34 @@ impl<'a> Parser<'a> {
1132511325
str.push_str(s);
1132611326
self.advance_token();
1132711327
}
11328+
} else if self
11329+
.dialect
11330+
.supports_string_literal_concatenation_with_newline()
11331+
{
11332+
// We are iterating over tokens including whitespaces, to identify
11333+
// string literals separated by newlines so we can concatenate them.
11334+
let mut after_newline = false;
11335+
loop {
11336+
match self.peek_token_no_skip().token {
11337+
Token::Whitespace(Whitespace::Newline) => {
11338+
after_newline = true;
11339+
self.next_token_no_skip();
11340+
}
11341+
Token::Whitespace(_) => {
11342+
self.next_token_no_skip();
11343+
}
11344+
Token::SingleQuotedString(ref s) | Token::DoubleQuotedString(ref s)
11345+
if after_newline =>
11346+
{
11347+
str.push_str(s.clone().as_str());
11348+
self.next_token_no_skip();
11349+
after_newline = false;
11350+
}
11351+
_ => break,
11352+
}
11353+
}
1132811354
}
11355+
1132911356
str
1133011357
}
1133111358

tests/sqlparser_common.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17712,6 +17712,25 @@ fn parse_adjacent_string_literal_concatenation() {
1771217712

1771317713
let sql = "SELECT * FROM t WHERE col = 'Hello' \n ' ' \t 'World!'";
1771417714
dialects.one_statement_parses_to(sql, r"SELECT * FROM t WHERE col = 'Hello World!'");
17715+
17716+
let dialects = all_dialects_where(|d| d.supports_string_literal_concatenation_with_newline());
17717+
let sql = r#"
17718+
SELECT 'abc' in ('a'
17719+
'b'
17720+
'c',
17721+
'd'
17722+
)"#;
17723+
dialects.one_statement_parses_to(sql, "SELECT 'abc' IN ('abc', 'd')");
17724+
17725+
let sql = r#"
17726+
SELECT 'abc' in ('a'
17727+
'b'
17728+
-- COMMENT
17729+
'c',
17730+
-- COMMENT
17731+
'd'
17732+
)"#;
17733+
dialects.one_statement_parses_to(sql, "SELECT 'abc' IN ('abc', 'd')");
1771517734
}
1771617735

1771717736
#[test]

0 commit comments

Comments
 (0)