diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java index efe3303bd950e49f40e55b61bbca2cddf807b14f..c91bacbfdc7435e35a6be7cc1f756381de968424 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java @@ -5,7 +5,6 @@ import com.google.common.collect.RangeSet; import com.google.common.collect.TreeRangeSet; import com.taosdata.jdbc.enums.TimestampPrecision; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.sql.Date; import java.sql.Time; @@ -110,15 +109,27 @@ public class Utils { return rawSql; // toLowerCase String preparedSql = rawSql.trim().toLowerCase(); - String[] clause = new String[]{"values\\s*\\([\\s\\S]*?\\)", "tags\\s*\\([\\s\\S]*?\\)", "where[\\s\\S]*"}; + String[] clause = new String[]{"tags\\s*\\([\\s\\S]*?\\)", "where[\\s\\S]*"}; Map placeholderPositions = new HashMap<>(); RangeSet clauseRangeSet = TreeRangeSet.create(); findPlaceholderPosition(preparedSql, placeholderPositions); + // find tags and where clause's position findClauseRangeSet(preparedSql, clause, clauseRangeSet); + // find values clause's position + findValuesClauseRangeSet(preparedSql, clauseRangeSet); return transformSql(rawSql, parameters, placeholderPositions, clauseRangeSet); } + private static void findValuesClauseRangeSet(String preparedSql, RangeSet clauseRangeSet) { + Matcher matcher = Pattern.compile("(values|,)\\s*(\\([^)]*\\))").matcher(preparedSql); + while (matcher.find()) { + int start = matcher.start(2); + int end = matcher.end(2); + clauseRangeSet.add(Range.closedOpen(start, end)); + } + } + private static void findClauseRangeSet(String preparedSql, String[] regexArr, RangeSet clauseRangeSet) { clauseRangeSet.clear(); for (String regex : regexArr) { @@ -126,7 +137,7 @@ public class Utils { while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); - clauseRangeSet.add(Range.closed(start, end)); + clauseRangeSet.add(Range.closedOpen(start, end)); } } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java index ee83f6ceb2d412613129611e2a575a7ad4922db0..4b8ec61078e8dbb812940d62737c638dc9a49f41 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java @@ -3,6 +3,8 @@ package com.taosdata.jdbc.utils; import org.junit.Assert; import org.junit.Test; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Stream; public class UtilsTest { @@ -32,7 +34,7 @@ public class UtilsTest { } @Test - public void getNativeSqlReplaceQuestionMarks() { + public void lowerCase() { // given String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)"; Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray(); @@ -46,7 +48,7 @@ public class UtilsTest { } @Test - public void getNativeSqlReplaceQuestionMarks2() { + public void upperCase() { // given String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)"; Object[] parameters = Stream.of("d1", 1, 123, 3.14, 220, 4).toArray(); @@ -59,9 +61,49 @@ public class UtilsTest { Assert.assertEquals(expected, actual); } + @Test + public void multiValues() { + // given + String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?),(?,?,?,?)"; + Object[] parameters = Stream.of("d1", 1, 100, 3.14, "abc", 4, 200, 3.1415, "xyz", 5).toArray(); + + // when + String actual = Utils.getNativeSql(nativeSql, parameters); + + // then + String expected = "INSERT INTO d1 (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (1) VALUES (100,3.14,'abc',4),(200,3.1415,'xyz',5)"; + Assert.assertEquals(expected, actual); + } + + @Test + public void lineTerminator() { + // given + String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,\r\n?,?),(?,?,?,?)"; + Object[] parameters = Stream.of("d1", 1, 100, 3.14, "abc", 4, 200, 3.1415, "xyz", 5).toArray(); + + // when + String actual = Utils.getNativeSql(nativeSql, parameters); + + // then + String expected = "INSERT INTO d1 (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (1) VALUES (100,3.14,\r\n'abc',4),(200,3.1415,'xyz',5)"; + Assert.assertEquals(expected, actual); + } + + @Test + public void lineTerminatorAndMultiValues() { + String nativeSql = "INSERT Into ? TAGS(?) VALUES(?,?,\r\n?,?),(?,? ,\r\n?,?) t? tags (?) Values (?,?,?\r\n,?),(?,?,?,?) t? Tags(?) values (?,?,?,?) , (?,?,?,?)"; + Object[] parameters = Stream.of("t1", "abc", 100, 1.1, "xxx", "xxx", 200, 2.2, "xxx", "xxx", 2, "bcd", 300, 3.3, "xxx", "xxx", 400, 4.4, "xxx", "xxx", 3, "cde", 500, 5.5, "xxx", "xxx", 600, 6.6, "xxx", "xxx").toArray(); + + // when + String actual = Utils.getNativeSql(nativeSql, parameters); + + // then + String expected = "INSERT Into t1 TAGS('abc') VALUES(100,1.1,\r\n'xxx','xxx'),(200,2.2 ,\r\n'xxx','xxx') t2 tags ('bcd') Values (300,3.3,'xxx'\r\n,'xxx'),(400,4.4,'xxx','xxx') t3 Tags('cde') values (500,5.5,'xxx','xxx') , (600,6.6,'xxx','xxx')"; + Assert.assertEquals(expected, actual); + } @Test - public void getNativeSqlReplaceNothing() { + public void replaceNothing() { // given String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)"; @@ -73,7 +115,7 @@ public class UtilsTest { } @Test - public void getNativeSqlReplaceNothing2() { + public void replaceNothing2() { // given String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)"; Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray(); @@ -86,7 +128,7 @@ public class UtilsTest { } @Test - public void getNativeSqlReplaceNothing3() { + public void replaceNothing3() { // given String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)";