[ZEPPELIN-2554] fix parsing backslash and single quote, tests

This commit is contained in:
Tinkoff DWH 2017-05-22 10:04:44 +05:00
parent af508f1ca4
commit e8be7b36dd
2 changed files with 40 additions and 23 deletions

View file

@ -499,7 +499,6 @@ public class JDBCInterpreter extends Interpreter {
StringBuilder query = new StringBuilder();
char character;
Boolean backslash = false;
Boolean multiLineComment = false;
Boolean singleLineComment = false;
Boolean quoteString = false;
@ -508,12 +507,6 @@ public class JDBCInterpreter extends Interpreter {
for (int item = 0; item < sql.length(); item++) {
character = sql.charAt(item);
if (backslash) {
query.append(character);
backslash = false;
continue;
}
if ((singleLineComment && (character == '\n' || item == sql.length() - 1))
|| (multiLineComment && character == '/' && sql.charAt(item - 1) == '*')) {
singleLineComment = false;
@ -528,10 +521,6 @@ public class JDBCInterpreter extends Interpreter {
continue;
}
if (character == '\\') {
backslash = true;
}
if (character == '\'') {
if (quoteString) {
quoteString = false;
@ -541,7 +530,7 @@ public class JDBCInterpreter extends Interpreter {
}
if (character == '"') {
if (doubleQuoteString) {
if (doubleQuoteString && item > 0) {
doubleQuoteString = false;
} else if (!quoteString) {
doubleQuoteString = true;
@ -561,7 +550,7 @@ public class JDBCInterpreter extends Interpreter {
}
}
if (character == ';' && !backslash && !quoteString && !doubleQuoteString) {
if (character == ';' && !quoteString && !doubleQuoteString) {
queries.add(StringUtils.trim(query.toString()));
query = new StringBuilder();
} else if (item == sql.length() - 1) {

View file

@ -27,8 +27,11 @@ import static org.junit.Assert.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.*;
import java.util.ArrayList;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Properties;
@ -175,31 +178,56 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
String sqlQuery = "insert into test_table(id, name) values ('a', ';\"');" +
"select * from test_table;" +
"select * from test_table WHERE ID = \";'\";" +
"select * from test_table WHERE ID = ';'";
"select * from test_table WHERE ID = ';';" +
"select '\n', ';';" +
"select replace('A\\;B', '\\', 'text');" +
"select '\\', ';';" +
"select '''', ';'";
Properties properties = new Properties();
JDBCInterpreter t = new JDBCInterpreter(properties);
t.open();
List<String> multipleSqlArray = t.splitSqlQueries(sqlQuery);
assertEquals(4, multipleSqlArray.size());
assertEquals(8, multipleSqlArray.size());
assertEquals("insert into test_table(id, name) values ('a', ';\"')", multipleSqlArray.get(0));
assertEquals("select * from test_table", multipleSqlArray.get(1));
assertEquals("select * from test_table WHERE ID = \";'\"", multipleSqlArray.get(2));
assertEquals("select * from test_table WHERE ID = ';'", multipleSqlArray.get(3));
assertEquals("select '\n', ';'", multipleSqlArray.get(4));
assertEquals("select replace('A\\;B', '\\', 'text')", multipleSqlArray.get(5));
assertEquals("select '\\', ';'", multipleSqlArray.get(6));
assertEquals("select '''', ';'", multipleSqlArray.get(7));
}
@Test
public void testSqlQueryWithBackslash() throws SQLException, IOException {
public void testQueryWithEsсapedCharacters() throws SQLException, IOException {
String sqlQuery = "select '\\n', ';';" +
"select replace('A\\;B', '\\', 'text')";
"select replace('A\\;B', '\\', 'text');" +
"select '\\', ';';" +
"select '''', ';'";
Properties properties = new Properties();
properties.setProperty("common.max_count", "1000");
properties.setProperty("common.max_retry", "3");
properties.setProperty("default.driver", "org.h2.Driver");
properties.setProperty("default.url", getJdbcConnection());
properties.setProperty("default.user", "");
properties.setProperty("default.password", "");
JDBCInterpreter t = new JDBCInterpreter(properties);
t.open();
List<String> multipleSqlArray = t.splitSqlQueries(sqlQuery);
assertEquals(2, multipleSqlArray.size());
assertEquals("select '\\n', ';'", multipleSqlArray.get(0));
assertEquals("select replace('A\\;B', '\\', 'text')", multipleSqlArray.get(1));
InterpreterResult interpreterResult = t.interpret(sqlQuery, interpreterContext);
assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code());
assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType());
assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(1).getType());
assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(2).getType());
assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(3).getType());
assertEquals("'\\n'\t';'\n\\n\t;\n", interpreterResult.message().get(0).getData());
assertEquals("'Atext;B'\nAtext;B\n", interpreterResult.message().get(1).getData());
assertEquals("'\\'\t';'\n\\\t;\n", interpreterResult.message().get(2).getData());
assertEquals("''''\t';'\n'\t;\n", interpreterResult.message().get(3).getData());
}
@Test