Skip to content

Commit 477ca51

Browse files
authored
fix: backslash at end of string literal was misinterpreted (#4246)
SQL strings that contained a string literal with a backslash as the last character were misinterpreted by the statement parser as containing unclosed string literals. Fixes googleapis/java-spanner-jdbc#2303
1 parent 2349908 commit 477ca51

File tree

3 files changed

+8
-2
lines changed

3 files changed

+8
-2
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,8 +1033,9 @@ int skipQuoted(
10331033
} else if (supportsBackslashEscape()
10341034
&& currentChar == BACKSLASH
10351035
&& length > currentIndex + 1
1036-
&& sql.charAt(currentIndex + 1) == startQuote) {
1037-
// This is an escaped quote (e.g. 'foo\'bar').
1036+
&& (sql.charAt(currentIndex + 1) == startQuote
1037+
|| sql.charAt(currentIndex + 1) == BACKSLASH)) {
1038+
// This is an escaped quote (e.g. 'foo\'bar') or an escaped backslash (e.g. 'test\\').
10381039
// Note that in raw strings, the \ officially does not start an escape sequence, but the
10391040
// result is still the same, as in a raw string 'both characters are preserved'.
10401041
appendIfNotNull(result, currentChar);

google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SpannerStatementParserTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public void testSkip() {
5454
assertEquals("'foo\"bar\"'", skip("'foo\"bar\"' ", 0));
5555
assertEquals("\"foo'bar'\"", skip("\"foo'bar'\" ", 0));
5656
assertEquals("`foo'bar'`", skip("`foo'bar'` ", 0));
57+
assertEquals("'test\\\\'", skip("'test\\\\'", 0));
5758

5859
assertEquals("'''foo'bar'''", skip("'''foo'bar''' ", 0));
5960
assertEquals("'''foo\\'bar'''", skip("'''foo\\'bar''' ", 0));

google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,10 @@ public void testGoogleStandardSQLDialectConvertPositionalParametersToNamedParame
12681268
"@p1'''?it\\'?s \n ?it\\'?s'''@p2",
12691269
parser.convertPositionalParametersToNamedParameters('?', "?'''?it\\'?s \n ?it\\'?s'''?")
12701270
.sqlWithNamedParameters);
1271+
assertEquals(
1272+
"@p1'?test?\\\\'@p2",
1273+
parser.convertPositionalParametersToNamedParameters('?', "?'?test?\\\\'?")
1274+
.sqlWithNamedParameters);
12711275

12721276
assertUnclosedLiteral(parser, "?'?it\\'?s \n ?it\\'?s'?");
12731277
assertUnclosedLiteral(parser, "?'?it\\'?s \n ?it\\'?s?");

0 commit comments

Comments
 (0)