@@ -163,21 +163,18 @@ public static void splitSqlScript(String resource, String script, String separat
163163 }
164164 final boolean inComment = inLineComment || inBlockComment ;
165165
166- if (!inLiteral && !inComment && containsSubstringAtOffset (lowerCaseScriptContent , "BEGIN" , i )) {
166+ if (!inLiteral && !inComment && containsKeywordsAtOffset (lowerCaseScriptContent , "BEGIN" , i , separator , commentPrefix , blockCommentStartDelimiter )) {
167167 compoundStatementDepth ++;
168168 }
169- if (!inLiteral && !inComment && containsSubstringAtOffset (lowerCaseScriptContent , "END" , i )) {
169+ if (!inLiteral && !inComment && containsKeywordsAtOffset (lowerCaseScriptContent , "END" , i , separator , commentPrefix , blockCommentStartDelimiter )) {
170170 compoundStatementDepth --;
171171 }
172172 final boolean inCompoundStatement = compoundStatementDepth != 0 ;
173173
174174 if (!inLiteral && !inCompoundStatement ) {
175175 if (script .startsWith (separator , i )) {
176176 // we've reached the end of the current statement
177- if (sb .length () > 0 ) {
178- statements .add (sb .toString ());
179- sb = new StringBuilder ();
180- }
177+ sb = flushStringBuilder (sb , statements );
181178 i += separator .length () - 1 ;
182179 continue ;
183180 }
@@ -199,6 +196,7 @@ else if (script.startsWith(blockCommentStartDelimiter, i)) {
199196 int indexOfCommentEnd = script .indexOf (blockCommentEndDelimiter , i );
200197 if (indexOfCommentEnd > i ) {
201198 i = indexOfCommentEnd + blockCommentEndDelimiter .length () - 1 ;
199+ inBlockComment = false ;
202200 continue ;
203201 }
204202 else {
@@ -218,24 +216,57 @@ else if (c == ' ' || c == '\n' || c == '\t' || c == '\r') {
218216 }
219217 sb .append (c );
220218 }
221- if (StringUtils .isNotEmpty (sb .toString ())) {
222- statements .add (sb .toString ());
219+ flushStringBuilder (sb , statements );
220+ }
221+
222+ private static StringBuilder flushStringBuilder (StringBuilder sb , List <String > statements ) {
223+ if (sb .length () == 0 ) {
224+ return sb ;
223225 }
226+
227+ final String s = sb .toString ().trim ();
228+ if (StringUtils .isNotEmpty (s )) {
229+ statements .add (s );
230+ }
231+
232+ return new StringBuilder ();
224233 }
225234
235+ private static boolean isSeperator (char c , String separator , String commentPrefix ,
236+ String blockCommentStartDelimiter ) {
237+ return c == ' ' || c == '\r' || c == '\n' || c == '\t' ||
238+ c == separator .charAt (0 ) || c == separator .charAt (separator .length () - 1 ) ||
239+ c == commentPrefix .charAt (0 ) || c == blockCommentStartDelimiter .charAt (0 ) ||
240+ c == blockCommentStartDelimiter .charAt (blockCommentStartDelimiter .length () - 1 );
241+ }
242+
226243 private static boolean containsSubstringAtOffset (String lowercaseString , String substring , int offset ) {
227244 String lowercaseSubstring = substring .toLowerCase ();
228245
229246 return lowercaseString .startsWith (lowercaseSubstring , offset );
230247 }
231248
249+ private static boolean containsKeywordsAtOffset (String lowercaseString , String keywords , int offset ,
250+ String separator , String commentPrefix ,
251+ String blockCommentStartDelimiter ) {
252+ String lowercaseKeywords = keywords .toLowerCase ();
253+
254+ boolean backSeperated = (offset == 0 ) || isSeperator (lowercaseString .charAt (offset - 1 ),
255+ separator , commentPrefix , blockCommentStartDelimiter );
256+ boolean frontSeperated = (offset >= (lowercaseString .length () - keywords .length ())) ||
257+ isSeperator (lowercaseString .charAt (offset + keywords .length ()),
258+ separator , commentPrefix , blockCommentStartDelimiter );
259+
260+ return backSeperated && frontSeperated && lowercaseString .startsWith (lowercaseKeywords , offset );
261+ }
262+
232263 private static void checkArgument (boolean expression , String errorMessage ) {
233264 if (!expression ) {
234265 throw new IllegalArgumentException (errorMessage );
235266 }
236267 }
237268
238- /**
269+ /**
239270 * Does the provided SQL script contain the specified delimiter?
240271 * @param script the SQL script
241272 * @param delim String delimiting each statement - typically a ';' character
@@ -356,7 +387,7 @@ public ScriptLoadException(String message, Throwable cause) {
356387 }
357388 }
358389
359- private static class ScriptParseException extends RuntimeException {
390+ public static class ScriptParseException extends RuntimeException {
360391 public ScriptParseException (String format , String scriptPath ) {
361392 super (String .format (format , scriptPath ));
362393 }
0 commit comments