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));
+    }
 }