This is an automated email from the ASF dual-hosted git repository. zjffdu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push: new aea44a4 [ZEPPELIN-4512]. Move SqlSplitter from jdbc interpreter to zeppelin-interpreter aea44a4 is described below commit aea44a4f0decfff94830bbcdfa5499b96b89aa4a Author: Jeff Zhang <zjf...@apache.org> AuthorDate: Thu Dec 26 18:07:51 2019 +0800 [ZEPPELIN-4512]. Move SqlSplitter from jdbc interpreter to zeppelin-interpreter ### What is this PR for? This PR move the sql split logic from jdbc interpreter to zeppelin-interpreter, so that other interpreter can reuse it. Besides that, it also fix some bugs of sql splitter, and add more unit test to verify it. ### What type of PR is it? [Bug Fix | Refactoring] ### Todos * [ ] - Task ### What is the Jira issue? * https://jira.apache.org/jira/browse/ZEPPELIN-4512 ### How should this be tested? * CI pass ### Screenshots (if appropriate) ### Questions: * Does the licenses files need update? No * Is there breaking changes for older versions? No * Does this needs documentation? No Author: Jeff Zhang <zjf...@apache.org> Closes #3569 from zjffdu/ZEPPELIN-4512 and squashes the following commits: d1eb0f25b [Jeff Zhang] [ZEPPELIN-4512]. Move SqlSplitter from jdbc interpreter to zeppelin-interpreter --- .../org/apache/zeppelin/jdbc/JDBCInterpreter.java | 78 +----- .../apache/zeppelin/jdbc/JDBCInterpreterTest.java | 4 +- .../zeppelin/interpreter/util/SqlSplitter.java | 164 ++++++++++++ .../zeppelin/interpreter/util/SqlSplitterTest.java | 286 +++++++++++++++++++++ 4 files changed, 464 insertions(+), 68 deletions(-) diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java index 6260731..045a291 100644 --- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java +++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java @@ -33,6 +33,7 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.alias.CredentialProvider; import org.apache.hadoop.security.alias.CredentialProviderFactory; import org.apache.zeppelin.interpreter.BaseZeppelinContext; +import org.apache.zeppelin.interpreter.util.SqlSplitter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -146,6 +147,8 @@ public class JDBCInterpreter extends KerberosInterpreter { private int maxLineResults; private int maxRows; + private SqlSplitter sqlSplitter; + public JDBCInterpreter(Properties property) { super(property); jdbcUserConfigurationsMap = new HashMap<>(); @@ -218,6 +221,9 @@ public class JDBCInterpreter extends KerberosInterpreter { setMaxLineResults(); setMaxRows(); + + //TODO(zjffdu) Set different sql splitter for different sql dialects. + this.sqlSplitter = new SqlSplitter(); } protected boolean isKerboseEnabled() { @@ -597,71 +603,6 @@ public class JDBCInterpreter extends KerberosInterpreter { return updatedCount < 0 && columnCount <= 0 ? true : false; } - /* - inspired from https://github.com/postgres/pgadmin3/blob/794527d97e2e3b01399954f3b79c8e2585b908dd/ - pgadmin/dlg/dlgProperty.cpp#L999-L1045 - */ - protected ArrayList<String> splitSqlQueries(String sql) { - ArrayList<String> queries = new ArrayList<>(); - StringBuilder query = new StringBuilder(); - char character; - - Boolean multiLineComment = false; - Boolean singleLineComment = false; - Boolean quoteString = false; - Boolean doubleQuoteString = false; - - for (int item = 0; item < sql.length(); item++) { - character = sql.charAt(item); - - if (singleLineComment && (character == '\n' || item == sql.length() - 1)) { - singleLineComment = false; - } - - if (multiLineComment && character == '/' && sql.charAt(item - 1) == '*') { - multiLineComment = false; - } - - if (character == '\'') { - if (quoteString) { - quoteString = false; - } else if (!doubleQuoteString) { - quoteString = true; - } - } - - if (character == '"') { - if (doubleQuoteString && item > 0) { - doubleQuoteString = false; - } else if (!quoteString) { - doubleQuoteString = true; - } - } - - if (!quoteString && !doubleQuoteString && !multiLineComment && !singleLineComment - && sql.length() > item + 1) { - if (character == '-' && sql.charAt(item + 1) == '-') { - singleLineComment = true; - } else if (character == '/' && sql.charAt(item + 1) == '*') { - multiLineComment = true; - } - } - - if (character == ';' && !quoteString && !doubleQuoteString && !multiLineComment - && !singleLineComment) { - queries.add(StringUtils.trim(query.toString())); - query = new StringBuilder(); - } else if (item == sql.length() - 1) { - query.append(character); - queries.add(StringUtils.trim(query.toString())); - } else { - query.append(character); - } - } - - return queries; - } - public InterpreterResult executePrecode(InterpreterContext interpreterContext) { InterpreterResult interpreterResult = null; for (String propertyKey : basePropretiesMap.keySet()) { @@ -677,6 +618,11 @@ public class JDBCInterpreter extends KerberosInterpreter { return interpreterResult; } + //Just keep it for testing + protected List<String> splitSqlQueries(String text) { + return sqlSplitter.splitSql(text); + } + private InterpreterResult executeSql(String propertyKey, String sql, InterpreterContext interpreterContext) { Connection connection = null; @@ -712,7 +658,7 @@ public class JDBCInterpreter extends KerberosInterpreter { List<String> sqlArray; sql = sql.trim(); if (splitQuery) { - sqlArray = splitSqlQueries(sql); + sqlArray = sqlSplitter.splitSql(sql); } else { if (sql.endsWith(";")) { sql = sql.substring(0, sql.length() - 1); diff --git a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java index e08f071..d7d7677 100644 --- a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java +++ b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java @@ -246,7 +246,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { assertEquals("select '\\', ';'", multipleSqlArray.get(6)); assertEquals("select '''', ';'", multipleSqlArray.get(7)); assertEquals("select /*+ scan */ * from test_table", multipleSqlArray.get(8)); - assertEquals("--singleLineComment\nselect * from test_table", multipleSqlArray.get(9)); + assertEquals("select * from test_table", multipleSqlArray.get(9)); } @Test @@ -685,7 +685,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { "*/\n" + "-- a ; b\n" + "select * from test_table WHERE ID = ';--';\n" + - "select * from test_table WHERE ID = '/*' -- test"; + "select * from test_table WHERE ID = '/*'; -- test"; InterpreterResult interpreterResult = t.interpret(sqlQuery, interpreterContext); assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code()); diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/util/SqlSplitter.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/util/SqlSplitter.java new file mode 100644 index 0000000..95af0e0 --- /dev/null +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/util/SqlSplitter.java @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.interpreter.util; + + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Split text into multiple sql statements. + * + * inspired from https://github.com/postgres/pgadmin3/blob/794527d97e2e3b01399954f3b79c8e2585b908dd/ + * pgadmin/dlg/dlgProperty.cpp#L999-L1045 + * + * + */ +public class SqlSplitter { + + // it must be either 1 character or 2 character + private Set<String> singleLineCommentPrefixList = new HashSet<>(); + + public SqlSplitter() { + this.singleLineCommentPrefixList.add("--"); + } + + /** + * + * @param additionalSingleCommentPrefixList Besides the standard single line comment prefix '--', + * you can also specify other characters for sql dialect + */ + public SqlSplitter(String... additionalSingleCommentPrefixList) { + for (String singleLineCommentPrefix : additionalSingleCommentPrefixList) { + if (singleLineCommentPrefix.length() > 2) { + throw new RuntimeException("Invalid singleLineCommentPrefix: " + singleLineCommentPrefix + + ", it is at most 2 characters"); + } + this.singleLineCommentPrefixList.add(singleLineCommentPrefix); + } + } + + public List<String> splitSql(String text) { + text = text.trim(); + List<String> queries = new ArrayList<>(); + StringBuilder query = new StringBuilder(); + char character; + + boolean multiLineComment = false; + boolean singleLineComment = false; + boolean singleQuoteString = false; + boolean doubleQuoteString = false; + + for (int index = 0; index < text.length(); index++) { + character = text.charAt(index); + + // end of single line comment + if (singleLineComment && (character == '\n')) { + singleLineComment = false; + if (query.toString().trim().isEmpty()) { + continue; + } + } + + // end of multiple line comment + if (multiLineComment && character == '/' && text.charAt(index - 1) == '*') { + multiLineComment = false; + if (query.toString().trim().isEmpty()) { + continue; + } + } + + if (character == '\'') { + if (singleQuoteString) { + singleQuoteString = false; + } else if (!doubleQuoteString) { + singleQuoteString = true; + } + } + + if (character == '"') { + if (doubleQuoteString && index > 0) { + doubleQuoteString = false; + } else if (!singleQuoteString) { + doubleQuoteString = true; + } + } + + if (!singleQuoteString && !doubleQuoteString && !multiLineComment && !singleLineComment + && text.length() > (index + 1)) { + if (isSingleLineComment(text.charAt(index), text.charAt(index + 1))) { + singleLineComment = true; + } else if (text.charAt(index) == '/' && text.charAt(index + 1) == '*') { + multiLineComment = true; + } + } + + if (character == ';' && !singleQuoteString && !doubleQuoteString && !multiLineComment + && !singleLineComment) { + // meet semicolon + queries.add(query.toString().trim()); + query = new StringBuilder(); + } else if (index == (text.length() - 1)) { + // meet the last character + if (!singleLineComment && !multiLineComment) { + query.append(character); + queries.add(query.toString().trim()); + } + } else if (!singleLineComment && !multiLineComment) { + // normal case, not in single line comment and not in multiple line comment + query.append(character); + } else if (singleLineComment && !query.toString().trim().isEmpty()) { + // in single line comment, only add it to query when the single line comment is + // in the middle of sql statement + // e.g. + // select a -- comment + // from table_1 + query.append(character); + } else if (multiLineComment && !query.toString().trim().isEmpty()) { + // in multiple line comment, only add it to query when the multiple line comment + // is in the middle of sql statement. + // e.g. + // select a /* comment */ + // from table_1 + query.append(character); + } + } + + return queries; + } + + private boolean isSingleLineComment(char curChar, char nextChar) { + for (String singleCommentPrefix : singleLineCommentPrefixList) { + if (singleCommentPrefix.length() == 1) { + if (curChar == singleCommentPrefix.charAt(0)) { + return true; + } + } + if (singleCommentPrefix.length() == 2) { + if (curChar == singleCommentPrefix.charAt(0) && + nextChar == singleCommentPrefix.charAt(1)) { + return true; + } + } + } + return false; + } +} diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/util/SqlSplitterTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/util/SqlSplitterTest.java new file mode 100644 index 0000000..afb6289 --- /dev/null +++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/util/SqlSplitterTest.java @@ -0,0 +1,286 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.interpreter.util; + +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class SqlSplitterTest { + + @Test + public void testNormalSql() { + SqlSplitter sqlSplitter = new SqlSplitter(); + List<String> sqls = sqlSplitter.splitSql("show tables"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\nselect * from table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("select * from table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("show\ntables;\nselect * \nfrom table_1"); + assertEquals(2, sqls.size()); + assertEquals("show\ntables", sqls.get(0)); + assertEquals("select * \nfrom table_1", sqls.get(1)); + + } + + @Test + public void testSingleLineComment() { + SqlSplitter sqlSplitter = new SqlSplitter(); + List<String> sqls = sqlSplitter.splitSql("show tables;\n--comment_1"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n--comment_1"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n--comment_1;"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n--comment_1;\n"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("--comment_1;\nshow tables"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("--comment_1;\nshow tables;\n--comment_2"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\ndescribe table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("show tables;\n--comment_1;\ndescribe table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("select a\nfrom table_1;\ndescribe table_1;--comment_1"); + assertEquals(2, sqls.size()); + assertEquals("select a\nfrom table_1", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("--comment_1;\n--comment_2\n"); + assertEquals(0, sqls.size()); + + sqls = sqlSplitter.splitSql("select a -- comment\n from table_1"); + assertEquals(1, sqls.size()); + assertEquals("select a -- comment\n from table_1", sqls.get(0)); + } + + @Test + public void testMultipleLineComment() { + SqlSplitter sqlSplitter = new SqlSplitter(); + List<String> sqls = sqlSplitter.splitSql("show tables;\n/*comment_1*/"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n/*comment\n_1*/"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n/*comment_1;*/"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n/*comment\n_1;*/\n"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("/*comment_1;*/\nshow tables"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("/*comment_1*;*/\nshow tables;\n/*--comment_2*/"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n/*comment_1;*/\ndescribe table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("select a\nfrom table_1;\ndescribe table_1;/*comment_1*/"); + assertEquals(2, sqls.size()); + assertEquals("select a\nfrom table_1", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("/*comment_1;*/\n/*comment_2*/\n"); + assertEquals(0, sqls.size()); + + sqls = sqlSplitter.splitSql("select a /*comment*/ from table_1"); + assertEquals(1, sqls.size()); + assertEquals("select a /*comment*/ from table_1", sqls.get(0)); + } + + @Test + public void testInvalidSql() { + SqlSplitter sqlSplitter = new SqlSplitter(); + List<String> sqls = sqlSplitter.splitSql("select a from table_1 where a=' and b=1"); + assertEquals(1, sqls.size()); + assertEquals("select a from table_1 where a=' and b=1", sqls.get(0)); + + sqls = sqlSplitter.splitSql("--comment_1;\nselect a from table_1 where a=' and b=1"); + assertEquals(1, sqls.size()); + assertEquals("select a from table_1 where a=' and b=1", sqls.get(0)); + + sqls = sqlSplitter.splitSql("select a from table_1 where a=' and b=1;\n--comment_1"); + assertEquals(1, sqls.size()); + assertEquals("select a from table_1 where a=' and b=1;\n--comment_1", sqls.get(0)); + } + + @Test + public void testComplexSql() { + SqlSplitter sqlSplitter = new SqlSplitter(); + String text = "/* ; */\n" + + "-- /* comment\n" + + "--select * from test_table\n" + + "select * from test_table; /* some comment ; */\n" + + "/*\n" + + "select * from test_table;\n" + + "*/\n" + + "-- a ; b\n" + + "select * from test_table WHERE ID = ';--';\n" + + "select * from test_table WHERE ID = '/*'; -- test"; + List<String> sqls = sqlSplitter.splitSql(text); + assertEquals(3, sqls.size()); + assertEquals("select * from test_table", sqls.get(0)); + assertEquals("select * from test_table WHERE ID = ';--'", sqls.get(1)); + assertEquals("select * from test_table WHERE ID = '/*'", sqls.get(2)); + } + + @Test + public void testCustomSplitter_1() { + SqlSplitter sqlSplitter = new SqlSplitter("//"); + List<String> sqls = sqlSplitter.splitSql("show tables;\n//comment_1"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n//comment_1"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n//comment_1;"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n//comment_1;\n"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("//comment_1;\nshow tables"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("//comment_1;\nshow tables;\n//comment_2"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\ndescribe table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("show tables;\n//comment_1;\ndescribe table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("select a\nfrom table_1;\ndescribe table_1;//comment_1"); + assertEquals(2, sqls.size()); + assertEquals("select a\nfrom table_1", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("//comment_1;\n//comment_2\n"); + assertEquals(0, sqls.size()); + + sqls = sqlSplitter.splitSql("select a // comment\n from table_1"); + assertEquals(1, sqls.size()); + assertEquals("select a // comment\n from table_1", sqls.get(0)); + } + + @Test + public void testCustomSplitter_2() { + SqlSplitter sqlSplitter = new SqlSplitter("#"); + List<String> sqls = sqlSplitter.splitSql("show tables;\n#comment_1"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n#comment_1"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n#comment_1;"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\n#comment_1;\n"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("#comment_1;\nshow tables"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("#comment_1;\nshow tables;\n#comment_2"); + assertEquals(1, sqls.size()); + assertEquals("show tables", sqls.get(0)); + + sqls = sqlSplitter.splitSql("show tables;\ndescribe table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("show tables;\n#comment_1;\ndescribe table_1"); + assertEquals(2, sqls.size()); + assertEquals("show tables", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("select a\nfrom table_1;\ndescribe table_1;#comment_1"); + assertEquals(2, sqls.size()); + assertEquals("select a\nfrom table_1", sqls.get(0)); + assertEquals("describe table_1", sqls.get(1)); + + sqls = sqlSplitter.splitSql("#comment_1;\n#comment_2\n"); + assertEquals(0, sqls.size()); + + sqls = sqlSplitter.splitSql("select a # comment\n from table_1"); + assertEquals(1, sqls.size()); + assertEquals("select a # comment\n from table_1", sqls.get(0)); + } +}