Skip to content

Commit 00580e6

Browse files
yoavcloudayman-sigma
authored andcommitted
Redshift: Support implicit string concatenation using newline (apache#2167)
1 parent b40e9cb commit 00580e6

4 files changed

Lines changed: 63 additions & 0 deletions

File tree

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
@@ -11356,7 +11356,34 @@ impl<'a> Parser<'a> {
1135611356
str.push_str(s);
1135711357
self.advance_token();
1135811358
}
11359+
} else if self
11360+
.dialect
11361+
.supports_string_literal_concatenation_with_newline()
11362+
{
11363+
// We are iterating over tokens including whitespaces, to identify
11364+
// string literals separated by newlines so we can concatenate them.
11365+
let mut after_newline = false;
11366+
loop {
11367+
match self.peek_token_no_skip().token {
11368+
Token::Whitespace(Whitespace::Newline) => {
11369+
after_newline = true;
11370+
self.next_token_no_skip();
11371+
}
11372+
Token::Whitespace(_) => {
11373+
self.next_token_no_skip();
11374+
}
11375+
Token::SingleQuotedString(ref s) | Token::DoubleQuotedString(ref s)
11376+
if after_newline =>
11377+
{
11378+
str.push_str(s.clone().as_str());
11379+
self.next_token_no_skip();
11380+
after_newline = false;
11381+
}
11382+
_ => break,
11383+
}
11384+
}
1135911385
}
11386+
1136011387
str
1136111388
}
1136211389

tests/sqlparser_common.rs

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

1773917739
let sql = "SELECT * FROM t WHERE col = 'Hello' \n ' ' \t 'World!'";
1774017740
dialects.one_statement_parses_to(sql, r"SELECT * FROM t WHERE col = 'Hello World!'");
17741+
17742+
let dialects = all_dialects_where(|d| d.supports_string_literal_concatenation_with_newline());
17743+
let sql = r#"
17744+
SELECT 'abc' in ('a'
17745+
'b'
17746+
'c',
17747+
'd'
17748+
)"#;
17749+
dialects.one_statement_parses_to(sql, "SELECT 'abc' IN ('abc', 'd')");
17750+
17751+
let sql = r#"
17752+
SELECT 'abc' in ('a'
17753+
'b'
17754+
-- COMMENT
17755+
'c',
17756+
-- COMMENT
17757+
'd'
17758+
)"#;
17759+
dialects.one_statement_parses_to(sql, "SELECT 'abc' IN ('abc', 'd')");
1774117760
}
1774217761

1774317762
#[test]

0 commit comments

Comments
 (0)