You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2017/07/25 09:44:58 UTC
[11/24] kylin git commit: bugfix#1553 Computed column 隐式转换两端括号被截断
bugfix#1553 Computed column 隐式转换两端括号被截断
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/a2cb5335
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/a2cb5335
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/a2cb5335
Branch: refs/heads/2.1.x
Commit: a2cb53358e05af9093f9762157f84686569460fc
Parents: 11aa9ff
Author: Aron.tao <24...@qq.com>
Authored: Thu Jul 13 10:42:28 2017 +0800
Committer: Jiatao Tao <ji...@Kyligences-MacBook-Pro.local>
Committed: Fri Jul 21 14:11:16 2017 +0800
----------------------------------------------------------------------
.../metadata/model/tool/CalciteParser.java | 42 ++++++++++++++++++--
.../kylin/model/tool/CalciteParserTest.java | 19 ++++++++-
.../query/util/ConvertToComputedColumn.java | 3 +-
.../query/util/ConvertToComputedColumnTest.java | 11 +++++
4 files changed, 68 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/a2cb5335/core-metadata/src/main/java/org/apache/kylin/metadata/model/tool/CalciteParser.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/tool/CalciteParser.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/tool/CalciteParser.java
index 9b80969..5352708 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/tool/CalciteParser.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/tool/CalciteParser.java
@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
-import com.google.common.collect.Lists;
import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlLiteral;
@@ -39,6 +38,7 @@ import org.apache.calcite.sql.util.SqlVisitor;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
public class CalciteParser {
@@ -188,7 +188,11 @@ public class CalciteParser {
return sql.substring(prefix.length(), sql.length() - suffix.length());
}
- public static Pair<Integer, Integer> getReplacePos(SqlNode node, String... lines) {
+ public static Pair<Integer, Integer> getReplacePos(SqlNode node, String inputSql) {
+ if (inputSql == null) {
+ return Pair.of(0, 0);
+ }
+ String[] lines = inputSql.split("\n");
SqlParserPos pos = node.getParserPosition();
int lineStart = pos.getLineNum();
int lineEnd = pos.getEndLineNum();
@@ -201,6 +205,38 @@ public class CalciteParser {
for (int i = 0; i < lineEnd - 1; i++) {
columnEnd += lines[i].length() + 1;
}
- return Pair.of(columnStart, columnEnd);
+ //for calcite's bug CALCITE-1875
+ Pair<Integer, Integer> startEndPos = getPosWithBracketsCompletion(inputSql, columnStart, columnEnd);
+ return startEndPos;
+ }
+
+ private static Pair<Integer, Integer> getPosWithBracketsCompletion(String inputSql, int left, int right) {
+ int leftBracketNum = 0;
+ int rightBracketNum = 0;
+ String substring = inputSql.substring(left, right);
+ for (int i = 0; i < substring.length(); i++) {
+ char temp = substring.charAt(i);
+ if (temp == '(') {
+ leftBracketNum++;
+ }
+ if (temp == ')') {
+ rightBracketNum++;
+ if (leftBracketNum < rightBracketNum) {
+ while ('(' != inputSql.charAt(left - 1)) {
+ left--;
+ }
+ left--;
+ leftBracketNum++;
+ }
+ }
+ }
+ while (rightBracketNum < leftBracketNum) {
+ while (')' != inputSql.charAt(right)) {
+ right++;
+ }
+ right++;
+ rightBracketNum++;
+ }
+ return Pair.of(left, right);
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/a2cb5335/core-metadata/src/test/java/org/apache/kylin/model/tool/CalciteParserTest.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/test/java/org/apache/kylin/model/tool/CalciteParserTest.java b/core-metadata/src/test/java/org/apache/kylin/model/tool/CalciteParserTest.java
index 81c1c97..2da6c9e 100644
--- a/core-metadata/src/test/java/org/apache/kylin/model/tool/CalciteParserTest.java
+++ b/core-metadata/src/test/java/org/apache/kylin/model/tool/CalciteParserTest.java
@@ -95,8 +95,7 @@ public class CalciteParserTest {
for (String sql : sqls) {
SqlNode parse = ((SqlSelect) CalciteParser.parse(sql)).getSelectList().get(0);
- String[] lines = sql.split("\n");
- Pair<Integer, Integer> replacePos = CalciteParser.getReplacePos(parse, lines);
+ Pair<Integer, Integer> replacePos = CalciteParser.getReplacePos(parse, sql);
String substring = sql.substring(replacePos.getLeft(), replacePos.getRight());
Preconditions.checkArgument(substring.startsWith("a"));
Preconditions.checkArgument(substring.endsWith("b"));
@@ -120,4 +119,20 @@ public class CalciteParserTest {
assertEquals(true, CalciteParser.isNodeEqual(sn0, sn2));
assertEquals(false, CalciteParser.isNodeEqual(sn0, sn3));
}
+
+ @Test
+ public void testPosWithBrackets() throws SqlParseException {
+ String[] sqls = new String[] {
+ "select ( a + b) * (c+ d ) from t", "select (a+b) * (c+d) from t",
+ "select (a + b) * (c+ d) from t", "select (a+b) * (c+d) from t",
+ };
+
+ for (String sql : sqls) {
+ SqlNode parse = ((SqlSelect) CalciteParser.parse(sql)).getSelectList().get(0);
+ Pair<Integer, Integer> replacePos = CalciteParser.getReplacePos(parse, sql);
+ String substring = sql.substring(replacePos.getLeft(), replacePos.getRight());
+ Preconditions.checkArgument(substring.startsWith("("));
+ Preconditions.checkArgument(substring.endsWith(")"));
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/a2cb5335/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java b/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java
index c9feaab..ad42b96 100644
--- a/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java
+++ b/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java
@@ -74,7 +74,6 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
return inputSql;
}
String result = inputSql;
- String[] lines = inputSql.split("\n");
List<Pair<String, String>> toBeReplacedExp = new ArrayList<>(); //{"alias":"expression"}, like {"t1":"t1.a+t1.b+t1.c"}
for (String ccExp : computedColumn.keySet()) {
@@ -86,7 +85,7 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
return inputSql;
}
for (SqlNode node : matchedNodes) {
- Pair<Integer, Integer> startEndPos = CalciteParser.getReplacePos(node, lines);
+ Pair<Integer, Integer> startEndPos = CalciteParser.getReplacePos(node, inputSql);
int start = startEndPos.getLeft();
int end = startEndPos.getRight();
//add table alias like t1.column,if exists alias
http://git-wip-us.apache.org/repos/asf/kylin/blob/a2cb5335/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java
----------------------------------------------------------------------
diff --git a/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java b/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java
index f9b8d8b..d9910fe 100644
--- a/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java
+++ b/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java
@@ -110,4 +110,15 @@ public class ConvertToComputedColumnTest {
}
+ @Test
+ public void testCCWithBrackets() {
+ String sql0 = "select ( a + b) + (c+d \t\n) from t";
+ String expr1 = "a + b + (c + d)";
+
+ Map<String, String> map = new HashMap<>();
+ map.put("cc0", expr1);
+ ImmutableSortedMap<String, String> computedColumns = ConvertToComputedColumn.getMapSortedByValue(map);
+ Assert.assertEquals("select cc0 from t",
+ ConvertToComputedColumn.replaceComputedColumn(sql0, computedColumns));
+ }
}