diff --git a/core/src/main/antlr4/org/jdbi/v3/core/internal/lexer/SqlScriptLexer.g4 b/core/src/main/antlr4/org/jdbi/v3/core/internal/lexer/SqlScriptLexer.g4 index 1fd044e2c3..a1cf0b7197 100644 --- a/core/src/main/antlr4/org/jdbi/v3/core/internal/lexer/SqlScriptLexer.g4 +++ b/core/src/main/antlr4/org/jdbi/v3/core/internal/lexer/SqlScriptLexer.g4 @@ -14,6 +14,8 @@ lexer grammar SqlScriptLexer; +options { caseInsensitive = true; } + COMMENT : '--' ~('\r' | '\n')* | '//' ~('\r' | '\n')* | @@ -33,10 +35,22 @@ fragment NEWLINE : ('\r' | '\n') ; +fragment WHITESPACE + : (' ' | '\t' | NEWLINE) + ; + QUOTED_TEXT : ('\'' (ESCAPE_SEQUENCE | ~'\'')* '\'') ; +BLOCK_BEGIN + : 'BEGIN' WHITESPACE+ + ; + +BLOCK_END + : 'END' WHITESPACE+ + ; + fragment ESCAPE_SEQUENCE : '\\' '\'' ; @@ -46,7 +60,7 @@ SEMICOLON ; LITERAL - : ('a'..'z'|'A'..'Z'|' '|'\t'|'0'..'9'| + : ('A'..'Z'|' '|'\t'|'0'..'9'| ','|'*'|'.'|'@'|'_'|'!'|'='|'('|')'|'['|']')+ ; diff --git a/core/src/main/java/org/jdbi/v3/core/internal/SqlScriptParser.java b/core/src/main/java/org/jdbi/v3/core/internal/SqlScriptParser.java index 240955781e..bd96fc8e6d 100644 --- a/core/src/main/java/org/jdbi/v3/core/internal/SqlScriptParser.java +++ b/core/src/main/java/org/jdbi/v3/core/internal/SqlScriptParser.java @@ -18,6 +18,16 @@ import org.jdbi.v3.core.internal.lexer.SqlScriptLexer; import org.jdbi.v3.core.statement.internal.ErrorListener; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.BLOCK_BEGIN; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.BLOCK_END; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.COMMENT; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.LITERAL; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.MULTI_LINE_COMMENT; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.NEWLINES; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.OTHER; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.QUOTED_TEXT; +import static org.jdbi.v3.core.internal.lexer.SqlScriptLexer.SEMICOLON; + /** * An SQL script parser. * @@ -37,26 +47,37 @@ public String parse(CharStream charStream) { SqlScriptLexer lexer = new SqlScriptLexer(charStream); lexer.addErrorListener(new ErrorListener()); boolean endOfFile = false; + int blockLevel = 0; while (!endOfFile) { Token t = lexer.nextToken(); switch (t.getType()) { case Token.EOF: endOfFile = true; break; - case SqlScriptLexer.SEMICOLON: - semicolonHandler.handle(t, sb); + case SEMICOLON: + if (blockLevel == 0) { + semicolonHandler.handle(t, sb); + } else { + // preserve semicolons within begin/end block + sb.append(t.getText()); + } + break; + case BLOCK_BEGIN: + case BLOCK_END: + blockLevel += BLOCK_BEGIN == t.getType() ? +1 : -1; + sb.append(t.getText()); break; - case SqlScriptLexer.COMMENT: - case SqlScriptLexer.MULTI_LINE_COMMENT: + case COMMENT: + case MULTI_LINE_COMMENT: break; - case SqlScriptLexer.NEWLINES: + case NEWLINES: if (sb.length() > 0) { - sb.append(' '); + sb.append(System.lineSeparator()); // normalize newline sequences } break; - case SqlScriptLexer.QUOTED_TEXT: - case SqlScriptLexer.LITERAL: - case SqlScriptLexer.OTHER: + case QUOTED_TEXT: + case LITERAL: + case OTHER: sb.append(t.getText()); break; default: diff --git a/core/src/main/java/org/jdbi/v3/core/statement/Script.java b/core/src/main/java/org/jdbi/v3/core/statement/Script.java index 0f0d105d80..98775576e8 100644 --- a/core/src/main/java/org/jdbi/v3/core/statement/Script.java +++ b/core/src/main/java/org/jdbi/v3/core/statement/Script.java @@ -21,7 +21,7 @@ import org.jdbi.v3.core.internal.SqlScriptParser; /** - * Represents a number of SQL statements which will be executed in a batch statement. + * Represents a number of SQL statements delimited by semicolon which will be executed in order in a batch statement. */ public class Script extends SqlStatement