Skip to content

Commit 0062599

Browse files
committed
Redshift: Support implicit string concatenation using newline
1 parent 46f2234 commit 0062599

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
@@ -11273,7 +11273,34 @@ impl<'a> Parser<'a> {
1127311273
str.push_str(s.clone().as_str());
1127411274
self.advance_token();
1127511275
}
11276+
} else if self
11277+
.dialect
11278+
.supports_string_literal_concatenation_with_newline()
11279+
{
11280+
// We are iterating over tokens including whitespaces, to identify
11281+
// string literals separated by newlines so we can concatenate them.
11282+
let mut after_newline = false;
11283+
loop {
11284+
match self.peek_token_no_skip().token {
11285+
Token::Whitespace(Whitespace::Newline) => {
11286+
after_newline = true;
11287+
self.next_token_no_skip();
11288+
}
11289+
Token::Whitespace(_) => {
11290+
self.next_token_no_skip();
11291+
}
11292+
Token::SingleQuotedString(ref s) | Token::DoubleQuotedString(ref s)
11293+
if after_newline =>
11294+
{
11295+
str.push_str(s.clone().as_str());
11296+
self.next_token_no_skip();
11297+
after_newline = false;
11298+
}
11299+
_ => break,
11300+
}
11301+
}
1127611302
}
11303+
1127711304
str
1127811305
}
1127911306

tests/sqlparser_common.rs

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

1764817648
let sql = "SELECT * FROM t WHERE col = 'Hello' \n ' ' \t 'World!'";
1764917649
dialects.one_statement_parses_to(sql, r"SELECT * FROM t WHERE col = 'Hello World!'");
17650+
17651+
let dialects = all_dialects_where(|d| d.supports_string_literal_concatenation_with_newline());
17652+
let sql = r#"
17653+
SELECT 'abc' in ('a'
17654+
'b'
17655+
'c',
17656+
'd'
17657+
)"#;
17658+
dialects.one_statement_parses_to(sql, "SELECT 'abc' IN ('abc', 'd')");
17659+
17660+
let sql = r#"
17661+
SELECT 'abc' in ('a'
17662+
'b'
17663+
-- COMMENT
17664+
'c',
17665+
-- COMMENT
17666+
'd'
17667+
)"#;
17668+
dialects.one_statement_parses_to(sql, "SELECT 'abc' IN ('abc', 'd')");
1765017669
}
1765117670

1765217671
#[test]

0 commit comments

Comments
 (0)