Fix for ScriptUtils failure when '--' occurs inside a multi-line comment on the same line as '*/' (#22392)
* Test for multi-line comment block where the comment end delimiter occurs on a line starting with the single-line comment prefix * ScriptUtils successfully parses a SQL script containing a multi-line comment block where the comment-end delimiter occurs on a line starting with the single-line comment prefix.
This commit is contained in:
parent
a698adf125
commit
82dbde13b6
|
@ -259,7 +259,7 @@ public abstract class ScriptUtils {
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
||||||
static String readScript(EncodedResource resource) throws IOException {
|
static String readScript(EncodedResource resource) throws IOException {
|
||||||
return readScript(resource, DEFAULT_COMMENT_PREFIX, DEFAULT_STATEMENT_SEPARATOR);
|
return readScript(resource, DEFAULT_COMMENT_PREFIX, DEFAULT_STATEMENT_SEPARATOR, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,15 +273,16 @@ public abstract class ScriptUtils {
|
||||||
* @param commentPrefix the prefix that identifies comments in the SQL script —
|
* @param commentPrefix the prefix that identifies comments in the SQL script —
|
||||||
* typically "--"
|
* typically "--"
|
||||||
* @param separator the statement separator in the SQL script — typically ";"
|
* @param separator the statement separator in the SQL script — typically ";"
|
||||||
|
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter
|
||||||
* @return a {@code String} containing the script lines
|
* @return a {@code String} containing the script lines
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
||||||
private static String readScript(EncodedResource resource, @Nullable String commentPrefix,
|
private static String readScript(EncodedResource resource, @Nullable String commentPrefix,
|
||||||
@Nullable String separator) throws IOException {
|
@Nullable String separator, @Nullable String blockCommentEndDelimiter) throws IOException {
|
||||||
|
|
||||||
LineNumberReader lnr = new LineNumberReader(resource.getReader());
|
LineNumberReader lnr = new LineNumberReader(resource.getReader());
|
||||||
try {
|
try {
|
||||||
return readScript(lnr, commentPrefix, separator);
|
return readScript(lnr, commentPrefix, separator, blockCommentEndDelimiter);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
lnr.close();
|
lnr.close();
|
||||||
|
@ -297,19 +298,21 @@ public abstract class ScriptUtils {
|
||||||
* a statement — will be included in the results.
|
* a statement — will be included in the results.
|
||||||
* @param lineNumberReader the {@code LineNumberReader} containing the script
|
* @param lineNumberReader the {@code LineNumberReader} containing the script
|
||||||
* to be processed
|
* to be processed
|
||||||
* @param commentPrefix the prefix that identifies comments in the SQL script —
|
* @param lineCommentPrefix the prefix that identifies comments in the SQL script —
|
||||||
* typically "--"
|
* typically "--"
|
||||||
* @param separator the statement separator in the SQL script — typically ";"
|
* @param separator the statement separator in the SQL script — typically ";"
|
||||||
|
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter
|
||||||
* @return a {@code String} containing the script lines
|
* @return a {@code String} containing the script lines
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
||||||
public static String readScript(LineNumberReader lineNumberReader, @Nullable String commentPrefix,
|
public static String readScript(LineNumberReader lineNumberReader, @Nullable String lineCommentPrefix,
|
||||||
@Nullable String separator) throws IOException {
|
@Nullable String separator, @Nullable String blockCommentEndDelimiter) throws IOException {
|
||||||
|
|
||||||
String currentStatement = lineNumberReader.readLine();
|
String currentStatement = lineNumberReader.readLine();
|
||||||
StringBuilder scriptBuilder = new StringBuilder();
|
StringBuilder scriptBuilder = new StringBuilder();
|
||||||
while (currentStatement != null) {
|
while (currentStatement != null) {
|
||||||
if (commentPrefix != null && !currentStatement.startsWith(commentPrefix)) {
|
if ((blockCommentEndDelimiter != null && currentStatement.contains(blockCommentEndDelimiter)) ||
|
||||||
|
(lineCommentPrefix != null && !currentStatement.startsWith(lineCommentPrefix))) {
|
||||||
if (scriptBuilder.length() > 0) {
|
if (scriptBuilder.length() > 0) {
|
||||||
scriptBuilder.append('\n');
|
scriptBuilder.append('\n');
|
||||||
}
|
}
|
||||||
|
@ -460,7 +463,7 @@ public abstract class ScriptUtils {
|
||||||
|
|
||||||
String script;
|
String script;
|
||||||
try {
|
try {
|
||||||
script = readScript(resource, commentPrefix, separator);
|
script = readScript(resource, commentPrefix, separator, blockCommentEndDelimiter);
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new CannotReadScriptException(resource, ex);
|
throw new CannotReadScriptException(resource, ex);
|
||||||
|
|
|
@ -162,6 +162,20 @@ public class ScriptUtilsUnitTests {
|
||||||
assertEquals("statement 2 not split correctly", statement2, statements.get(1));
|
assertEquals("statement 2 not split correctly", statement2, statements.get(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readAndSplitScriptContainingMultiLineNestedComments() throws Exception {
|
||||||
|
String script = readScript("test-data-with-multi-line-nested-comments.sql");
|
||||||
|
List<String> statements = new ArrayList<>();
|
||||||
|
splitSqlScript(script, ';', statements);
|
||||||
|
|
||||||
|
String statement1 = "INSERT INTO users(first_name, last_name) VALUES('Juergen', 'Hoeller')";
|
||||||
|
String statement2 = "INSERT INTO users(first_name, last_name) VALUES( 'Sam' , 'Brannen' )";
|
||||||
|
|
||||||
|
assertEquals("wrong number of statements", 2, statements.size());
|
||||||
|
assertEquals("statement 1 not split correctly", statement1, statements.get(0));
|
||||||
|
assertEquals("statement 2 not split correctly", statement2, statements.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void containsDelimiters() {
|
public void containsDelimiters() {
|
||||||
assertFalse(containsSqlScriptDelimiters("select 1\n select ';'", ";"));
|
assertFalse(containsSqlScriptDelimiters("select 1\n select ';'", ";"));
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* This is a multi line comment
|
||||||
|
* The next comment line has no text
|
||||||
|
|
||||||
|
* The next comment line starts with a space.
|
||||||
|
* x, y, z...
|
||||||
|
*/
|
||||||
|
|
||||||
|
INSERT INTO users(first_name, last_name) VALUES('Juergen', 'Hoeller');
|
||||||
|
-- This is also a comment.
|
||||||
|
/*-------------------------------------------
|
||||||
|
-- A fancy multi-line comments that puts
|
||||||
|
-- single line comments inside of a multi-line
|
||||||
|
-- comment block.
|
||||||
|
Moreover, the block commend end delimiter
|
||||||
|
appears on a line that can potentially also
|
||||||
|
be a single-line comment if we weren't
|
||||||
|
already inside a multi-line comment run.
|
||||||
|
-------------------------------------------*/
|
||||||
|
INSERT INTO
|
||||||
|
users(first_name, last_name) -- This is a single line comment containing the block-end-comment sequence here */ but it's still a single-line comment
|
||||||
|
VALUES( 'Sam' -- first_name
|
||||||
|
, 'Brannen' -- last_name
|
||||||
|
);--
|
Loading…
Reference in New Issue