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/03 07:44:12 UTC
[01/26] kylin git commit: fix ci
Repository: kylin
Updated Branches:
refs/heads/kylin-2.1.x [created] 82b578a56
fix ci
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/2f7aa456
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/2f7aa456
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/2f7aa456
Branch: refs/heads/kylin-2.1.x
Commit: 2f7aa456640885dfde622966a6d487579a117931
Parents: 8603297
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 29 12:34:03 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 29 13:51:45 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/rest/util/AdHocUtilTest.java | 45 ++++++++++----------
1 file changed, 22 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/2f7aa456/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
----------------------------------------------------------------------
diff --git a/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java b/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
index b93e2d3..724844c 100644
--- a/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
+++ b/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
@@ -30,36 +30,28 @@ public class AdHocUtilTest {
@Test
public void testReplaceIdentifierInExpr() {
{
- String ret = AdHocUtil.replaceIdentifierInExpr("a.b.x * a.b.y", null, false);
- Assert.assertEquals("b.x * b.y", ret);
+ String ret = AdHocUtil.replaceIdentifierInExpr("x * y", null, false);
+ Assert.assertEquals("x * y", ret);
}
{
- String ret = AdHocUtil.replaceIdentifierInExpr("a_1.b_2.x_3 * a_1.b_2.y_3", null, false);
+ String ret = AdHocUtil.replaceIdentifierInExpr("x_3 * y_3", "b_2", false);
Assert.assertEquals("b_2.x_3 * b_2.y_3", ret);
}
{
- String ret = AdHocUtil.replaceIdentifierInExpr("a.b.x * a.b.y", "c", false);
- Assert.assertEquals("c.x * c.y", ret);
+ String ret = AdHocUtil.replaceIdentifierInExpr("substr(x,1,3)>y", "c", true);
+ Assert.assertEquals("substr(c.x,1,3)>c.y", ret);
}
{
- String ret = AdHocUtil.replaceIdentifierInExpr("a.b.x * a.b.y", "c", true);
- Assert.assertEquals("\"C\".\"X\" * \"C\".\"Y\"", ret);
+ String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", "c", true);
+ Assert.assertEquals("strcmp(substr(c.x,1,3),c.y)", ret);
}
{
- String ret = AdHocUtil.replaceIdentifierInExpr("substr(a.b.x,1,3)>a.b.y", "c", true);
- Assert.assertEquals("substr(\"C\".\"X\",1,3)>\"C\".\"Y\"", ret);
+ String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", null, true);
+ Assert.assertEquals("strcmp(substr(x,1,3),y)", ret);
}
{
- String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(a.b.x,1,3),a.b.y) > 0", "c", true);
- Assert.assertEquals("strcmp(substr(\"C\".\"X\",1,3),\"C\".\"Y\") > 0", ret);
- }
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(a.b.x,1,3),a.b.y) > 0", null, true);
- Assert.assertEquals("strcmp(substr(\"B\".\"X\",1,3),\"B\".\"Y\") > 0", ret);
- }
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(a.b.x, 1, 3),a.b.y) > 0", null, false);
- Assert.assertEquals("strcmp(substr(b.x, 1, 3),b.y) > 0", ret);
+ String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", null, false);
+ Assert.assertEquals("strcmp(substr(x,1,3),y)", ret);
}
}
@@ -68,7 +60,7 @@ public class AdHocUtilTest {
ComputedColumnDesc computedColumnDesc = mock(ComputedColumnDesc.class);
when(computedColumnDesc.getColumnName()).thenReturn("DEAL_AMOUNT");
- when(computedColumnDesc.getExpression()).thenReturn("DB.TABLE.price * DB.TABLE.number");
+ when(computedColumnDesc.getExpression()).thenReturn("price * number");
CCInfo ccInfo = mock(CCInfo.class);
when(ccInfo.getComputedColumnDesc()).thenReturn(computedColumnDesc);
@@ -77,22 +69,29 @@ public class AdHocUtilTest {
String ret = AdHocUtil.restoreComputedColumnToExpr(
"select DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT", ccInfo);
Assert.assertEquals(
- "select (TABLE.price * TABLE.number) from DB.TABLE group by date order by (TABLE.price * TABLE.number)",
+ "select (price * number) from DB.TABLE group by date order by (price * number)",
ret);
}
{
String ret = AdHocUtil.restoreComputedColumnToExpr(
"select DEAL_AMOUNT as DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT", ccInfo);
Assert.assertEquals(
- "select (TABLE.price * TABLE.number) as DEAL_AMOUNT from DB.TABLE group by date order by (TABLE.price * TABLE.number)",
+ "select (price * number) as DEAL_AMOUNT from DB.TABLE group by date order by (price * number)",
ret);
}
{
String ret = AdHocUtil.restoreComputedColumnToExpr(
"select \"DEAL_AMOUNT\" AS deal_amount from DB.TABLE group by date order by DEAL_AMOUNT", ccInfo);
Assert.assertEquals(
- "select (\"TABLE\".\"PRICE\" * \"TABLE\".\"NUMBER\") AS deal_amount from DB.TABLE group by date order by (TABLE.price * TABLE.number)",
+ "select (price * number) AS deal_amount from DB.TABLE group by date order by (price * number)",
ret);
}
+ {
+ String ret = AdHocUtil.restoreComputedColumnToExpr(
+ "select x.DEAL_AMOUNT AS deal_amount from DB.TABLE x group by date order by x.DEAL_AMOUNT", ccInfo);
+ Assert.assertEquals(
+ "select (x.price * x.number) AS deal_amount from DB.TABLE x group by date order by (x.price * x.number)",
+ ret);
+ }
}
}
[03/26] kylin git commit: minor, enhance computed column checks
Posted by li...@apache.org.
minor, enhance computed column checks
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/d61f867f
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/d61f867f
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/d61f867f
Branch: refs/heads/kylin-2.1.x
Commit: d61f867ff9fa170e155310edeb03db6059433f2f
Parents: 69532cd
Author: Hongbin Ma <ma...@apache.org>
Authored: Wed Jun 28 21:13:25 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 29 13:51:45 2017 +0800
----------------------------------------------------------------------
core-metadata/pom.xml | 16 +-
.../apache/kylin/metadata/model/ColumnDesc.java | 15 +-
.../metadata/model/ComputedColumnDesc.java | 3 +
.../kylin/metadata/model/DataModelDesc.java | 30 ++-
.../apache/kylin/metadata/model/TblColRef.java | 2 +-
.../metadata/model/tool/CalciteParser.java | 203 +++++++++++++++++++
.../kylin/model/tool/CalciteParserTest.java | 111 ++++++++++
.../model_desc/ci_inner_join_model.json | 6 +-
.../model_desc/ci_left_join_model.json | 6 +-
.../query/util/ConvertToComputedColumn.java | 111 ++--------
.../query/util/ConvertToComputedColumnTest.java | 22 --
11 files changed, 379 insertions(+), 146 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/core-metadata/pom.xml
----------------------------------------------------------------------
diff --git a/core-metadata/pom.xml b/core-metadata/pom.xml
index f5ab12a..d45a838 100644
--- a/core-metadata/pom.xml
+++ b/core-metadata/pom.xml
@@ -17,7 +17,8 @@
limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -60,6 +61,19 @@
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.kylin</groupId>
+ <artifactId>atopcalcite</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica-core</artifactId>
+ </exclusion>
+ </exclusions>
+ <!--set to provided on purpose, so that dependant on metadata module will not depend on calcite unnecessarily-->
+ <!--https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html-->
+ <scope>provided</scope>
+ </dependency>
<!-- Compiled -->
<dependency>
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/core-metadata/src/main/java/org/apache/kylin/metadata/model/ColumnDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/ColumnDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/ColumnDesc.java
index 5d15d56..3c84c96 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/ColumnDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/ColumnDesc.java
@@ -19,9 +19,9 @@
package org.apache.kylin.metadata.model;
import java.io.Serializable;
-import java.util.regex.Pattern;
import org.apache.kylin.metadata.datatype.DataType;
+import org.apache.kylin.metadata.model.tool.CalciteParser;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
@@ -82,7 +82,8 @@ public class ColumnDesc implements Serializable {
this.index = other.index;
}
- public ColumnDesc(String id, String name, String datatype, String comment, String dataGen, String index, String computedColumnExpr) {
+ public ColumnDesc(String id, String name, String datatype, String comment, String dataGen, String index,
+ String computedColumnExpr) {
this.id = id;
this.name = name;
this.datatype = datatype;
@@ -193,11 +194,12 @@ public class ColumnDesc implements Serializable {
return index;
}
- public String getComputedColumnExpr(String tableAlias, String tableIdentity) {
+ public String getComputedColumnExpr(String tableAlias) {
Preconditions.checkState(computedColumnExpr != null);
+ Preconditions.checkState(tableAlias != null);
- //http://stackoverflow.com/questions/5054995/how-to-replace-case-insensitive-literal-substrings-in-java
- return computedColumnExpr.replaceAll("(?i)" + Pattern.quote(tableIdentity), tableAlias);
+ String s = CalciteParser.insertAliasInExpr(computedColumnExpr, tableAlias);
+ return s;
}
public boolean isComputedColumnn() {
@@ -257,6 +259,7 @@ public class ColumnDesc implements Serializable {
@Override
public String toString() {
- return "ColumnDesc{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", datatype='" + datatype + '\'' + ", comment='" + comment + '\'' + '}';
+ return "ColumnDesc{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", datatype='" + datatype + '\''
+ + ", comment='" + comment + '\'' + '}';
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/core-metadata/src/main/java/org/apache/kylin/metadata/model/ComputedColumnDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/ComputedColumnDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/ComputedColumnDesc.java
index 013cb8c..540b5fc 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/ComputedColumnDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/ComputedColumnDesc.java
@@ -20,6 +20,7 @@ package org.apache.kylin.metadata.model;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Preconditions;
+import org.apache.kylin.metadata.model.tool.CalciteParser;
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class ComputedColumnDesc {
@@ -42,6 +43,8 @@ public class ComputedColumnDesc {
tableIdentity = tableIdentity.toUpperCase();
columnName = columnName.toUpperCase();
+
+ CalciteParser.ensureNoTableNameExists(expression);
}
public String getFullName() {
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
index 7de955e..91802f7 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
@@ -489,17 +489,11 @@ public class DataModelDesc extends RootPersistentEntity {
}
CCInfo other = ccInfoMap.get(thisCCName);
- if (other == null || (other.getDataModelDescs().size() == 1 && other.getDataModelDescs().contains(this))) {
- //check whether two computer columns's definition is the same.
- for (CCInfo sysCCInfo : ccInfoMap.values()) {
- String definition0 = thisCCDesc.getExpression();
- String definition1 = sysCCInfo.getComputedColumnDesc().getExpression();
- if (isTwoCCDefinitionEquals(definition0, definition1)) {
- throw new IllegalStateException(String.format(
- "Computed column %s'definition: %s is already defined in other models: %s. Please change another definition, or try to keep consistent definition",
- thisCCName, definition0, sysCCInfo.getDataModelDescs()));
- }
- }
+
+ if (other == null) {
+ checkSameCCDefinition(ccInfoMap, thisCCDesc, thisCCName);
+ ccInfoMap.put(thisCCName, new CCInfo(thisCCDesc, Sets.<DataModelDesc> newHashSet(this)));
+ } else if (other.getDataModelDescs().size() == 1 && other.getDataModelDescs().contains(this)) {
ccInfoMap.put(thisCCName, new CCInfo(thisCCDesc, Sets.<DataModelDesc> newHashSet(this)));
} else if (other.getComputedColumnDesc().equals(thisCCDesc)) {
other.getDataModelDescs().add(this);
@@ -511,6 +505,20 @@ public class DataModelDesc extends RootPersistentEntity {
}
}
+ private void checkSameCCDefinition(Map<String, CCInfo> ccInfoMap, ComputedColumnDesc thisCCDesc,
+ String thisCCName) {
+ //check whether two computer columns's definition is the same.
+ for (CCInfo sysCCInfo : ccInfoMap.values()) {
+ String definition0 = thisCCDesc.getExpression();
+ String definition1 = sysCCInfo.getComputedColumnDesc().getExpression();
+ if (isTwoCCDefinitionEquals(definition0, definition1)) {
+ throw new IllegalStateException(String.format(
+ "Computed column %s's definition: %s is already defined in other models: %s. Please change another definition, or try to keep consistent definition",
+ thisCCName, definition0, sysCCInfo.getDataModelDescs()));
+ }
+ }
+ }
+
private boolean isTwoCCDefinitionEquals(String definition0, String definition1) {
definition0 = definition0.replaceAll("\\s*", "");
definition1 = definition1.replaceAll("\\s*", "");
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java
index 5a28e8b..5563856 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java
@@ -158,7 +158,7 @@ public class TblColRef implements Serializable {
if (!column.isComputedColumnn()) {
return getIdentity();
} else {
- return column.getComputedColumnExpr(getTableAlias(), table.getTableIdentity());
+ return column.getComputedColumnExpr(getTableAlias());
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/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
new file mode 100644
index 0000000..47a90bf
--- /dev/null
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/tool/CalciteParser.java
@@ -0,0 +1,203 @@
+/*
+ * 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.kylin.metadata.model.tool;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.util.SqlBasicVisitor;
+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;
+
+public class CalciteParser {
+ public static SqlNode parse(String sql) throws SqlParseException {
+ SqlParser.ConfigBuilder parserBuilder = SqlParser.configBuilder();
+ SqlParser sqlParser = SqlParser.create(sql, parserBuilder.build());
+ return sqlParser.parseQuery();
+ }
+
+ public static SqlNode getOnlySelectNode(String sql) {
+ SqlNodeList selectList = null;
+ try {
+ selectList = ((SqlSelect) CalciteParser.parse(sql)).getSelectList();
+ } catch (SqlParseException e) {
+ throw new RuntimeException("Failed to parse expression \'" + sql
+ + "\', please make sure the expression is valid and no table name exists in the expression");
+ }
+
+ Preconditions.checkArgument(selectList.size() == 1,
+ "Expression is invalid because size of select list exceeds one");
+
+ return selectList.get(0);
+ }
+
+ public static SqlNode getExpNode(String expr) {
+ return getOnlySelectNode("select " + expr + " from t");
+
+ }
+
+ public static boolean isNodeEqual(SqlNode node0, SqlNode node1) {
+ if (node0 == null) {
+ return node1 == null;
+ } else if (node1 == null) {
+ return false;
+ }
+
+ if (!Objects.equals(node0.getClass().getSimpleName(), node1.getClass().getSimpleName())) {
+ return false;
+ }
+
+ if (node0 instanceof SqlCall) {
+ SqlCall thisNode = (SqlCall) node0;
+ SqlCall thatNode = (SqlCall) node1;
+ if (!thisNode.getOperator().getName().equalsIgnoreCase(thatNode.getOperator().getName())) {
+ return false;
+ }
+ return isNodeEqual(thisNode.getOperandList(), thatNode.getOperandList());
+ }
+ if (node0 instanceof SqlLiteral) {
+ SqlLiteral thisNode = (SqlLiteral) node0;
+ SqlLiteral thatNode = (SqlLiteral) node1;
+ return Objects.equals(thisNode.getValue(), thatNode.getValue());
+ }
+ if (node0 instanceof SqlNodeList) {
+ SqlNodeList thisNode = (SqlNodeList) node0;
+ SqlNodeList thatNode = (SqlNodeList) node1;
+ if (thisNode.getList().size() != thatNode.getList().size()) {
+ return false;
+ }
+ for (int i = 0; i < thisNode.getList().size(); i++) {
+ SqlNode thisChild = thisNode.getList().get(i);
+ final SqlNode thatChild = thatNode.getList().get(i);
+ if (!isNodeEqual(thisChild, thatChild)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (node0 instanceof SqlIdentifier) {
+ SqlIdentifier thisNode = (SqlIdentifier) node0;
+ SqlIdentifier thatNode = (SqlIdentifier) node1;
+ // compare ignore table alias.eg: expression like "a.b + a.c + a.d" ,alias a will be ignored when compared
+ String name0 = thisNode.names.get(thisNode.names.size() - 1).replace("\"", "");
+ String name1 = thatNode.names.get(thatNode.names.size() - 1).replace("\"", "");
+ return name0.equalsIgnoreCase(name1);
+ }
+
+ return false;
+ }
+
+ private static boolean isNodeEqual(List<SqlNode> operands0, List<SqlNode> operands1) {
+ if (operands0.size() != operands1.size()) {
+ return false;
+ }
+ for (int i = 0; i < operands0.size(); i++) {
+ if (!isNodeEqual(operands0.get(i), operands1.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void ensureNoTableNameExists(String expr) {
+ SqlNode sqlNode = getExpNode(expr);
+
+ SqlVisitor sqlVisitor = new SqlBasicVisitor() {
+ @Override
+ public Object visit(SqlIdentifier id) {
+ if (id.names.size() > 1) {
+ throw new IllegalArgumentException("SqlIdentifier " + id + " contains DB/Table name");
+ }
+ return null;
+ }
+ };
+
+ sqlNode.accept(sqlVisitor);
+ }
+
+ public static String insertAliasInExpr(String expr, String alias) {
+ String prefix = "select ";
+ String suffix = " from t";
+ String sql = prefix + expr + suffix;
+ SqlNode sqlNode = getOnlySelectNode(sql);
+
+ final List<SqlIdentifier> sqlIdentifiers = Lists.newArrayList();
+ SqlVisitor sqlVisitor = new SqlBasicVisitor() {
+ @Override
+ public Object visit(SqlIdentifier id) {
+ if (id.names.size() > 1) {
+ throw new IllegalArgumentException("SqlIdentifier " + id + " contains DB/Table name");
+ }
+ sqlIdentifiers.add(id);
+ return null;
+ }
+ };
+
+ sqlNode.accept(sqlVisitor);
+
+ Collections.sort(sqlIdentifiers, new Comparator<SqlIdentifier>() {
+ @Override
+ public int compare(SqlIdentifier o1, SqlIdentifier o2) {
+ int linegap = o2.getParserPosition().getLineNum() - o1.getParserPosition().getLineNum();
+ if (linegap != 0)
+ return linegap;
+
+ return o2.getParserPosition().getColumnNum() - o1.getParserPosition().getColumnNum();
+ }
+ });
+
+ for (SqlIdentifier sqlIdentifier : sqlIdentifiers) {
+ Pair<Integer, Integer> replacePos = getReplacePos(sqlIdentifier, sql);
+ int start = replacePos.getLeft();
+ sql = sql.substring(0, start) + alias + "." + sql.substring(start);
+ }
+
+ return sql.substring(prefix.length(), sql.length() - suffix.length());
+ }
+
+ public static Pair<Integer, Integer> getReplacePos(SqlNode node, String... lines) {
+ SqlParserPos pos = node.getParserPosition();
+ int lineStart = pos.getLineNum();
+ int lineEnd = pos.getEndLineNum();
+ int columnStart = pos.getColumnNum() - 1;
+ int columnEnd = pos.getEndColumnNum();
+ //for the case that sql is multi lines
+ for (int i = 0; i < lineStart - 1; i++) {
+ columnStart += lines[i].length() + 1;
+ }
+ for (int i = 0; i < lineEnd - 1; i++) {
+ columnEnd += lines[i].length() + 1;
+ }
+ return Pair.of(columnStart, columnEnd);
+ }
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/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
new file mode 100644
index 0000000..acf7b5a
--- /dev/null
+++ b/core-metadata/src/test/java/org/apache/kylin/model/tool/CalciteParserTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.kylin.model.tool;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.kylin.metadata.model.tool.CalciteParser;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.google.common.base.Preconditions;
+
+public class CalciteParserTest {
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void testNoTableNameExists() throws SqlParseException {
+ String expr1 = "a + b";
+ Assert.assertEquals("x.a + x.b", CalciteParser.insertAliasInExpr(expr1, "x"));
+
+ String expr2 = "a + year(b)";
+ Assert.assertEquals("x.a + year(x.b)", CalciteParser.insertAliasInExpr(expr2, "x"));
+
+ String expr3 = "a + hiveudf(b)";
+ Assert.assertEquals("x.a + hiveudf(x.b)", CalciteParser.insertAliasInExpr(expr3, "x"));
+ }
+
+ @Test
+ public void testTableNameExists1() throws SqlParseException {
+ String expr1 = "a + x.b";
+
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage("SqlIdentifier X.B contains DB/Table name");
+ CalciteParser.insertAliasInExpr(expr1, "x");
+ }
+
+ @Test
+ public void testTableNameExists2() throws SqlParseException {
+ String expr1 = "a + year(x.b)";
+
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage("SqlIdentifier X.B contains DB/Table name");
+ CalciteParser.insertAliasInExpr(expr1, "x");
+ }
+
+ @Test
+ public void testTableNameExists3() throws SqlParseException {
+ String expr1 = "a + hiveudf(x.b)";
+
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage("SqlIdentifier X.B contains DB/Table name");
+ CalciteParser.insertAliasInExpr(expr1, "x");
+ }
+
+ @Test
+ public void testPos() throws SqlParseException {
+ String[] sqls = new String[] { "select \n a \n + \n b \n from t", //
+ "select\na\n+\nb\nfrom t", //
+ "select \r\n a \r\n + \r\n b \r\n from t", //
+ "select\r\na\r\n+\r\nb\r\nfrom t" };
+
+ 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);
+ String substring = sql.substring(replacePos.getLeft(), replacePos.getRight());
+ Preconditions.checkArgument(substring.startsWith("a"));
+ Preconditions.checkArgument(substring.endsWith("b"));
+ }
+
+ }
+
+ @Test
+ public void testEqual() throws SqlParseException {
+ String sql0 = "select a.a + a.b + a.c from t as a";
+ String sql1 = "select (((a . a + a.b + a.c))) from t as a";
+ String sql2 = "select (a + b) + c from t";
+ String sql3 = "select a.a + (a.b + a.c) from t as a";
+
+ SqlNode sn0 = CalciteParser.getOnlySelectNode(sql0);
+ SqlNode sn1 = CalciteParser.getOnlySelectNode(sql1);
+ SqlNode sn2 = CalciteParser.getOnlySelectNode(sql2);
+ SqlNode sn3 = CalciteParser.getOnlySelectNode(sql3);
+
+ Assert.assertEquals(true, CalciteParser.isNodeEqual(sn0, sn1));
+ Assert.assertEquals(true, CalciteParser.isNodeEqual(sn0, sn2));
+ Assert.assertEquals(false, CalciteParser.isNodeEqual(sn0, sn3));
+ }
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/examples/test_case_data/localmeta/model_desc/ci_inner_join_model.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/model_desc/ci_inner_join_model.json b/examples/test_case_data/localmeta/model_desc/ci_inner_join_model.json
index d084ce2..5225cf3 100644
--- a/examples/test_case_data/localmeta/model_desc/ci_inner_join_model.json
+++ b/examples/test_case_data/localmeta/model_desc/ci_inner_join_model.json
@@ -125,21 +125,21 @@
{
"tableIdentity": "DEFAULT.TEST_KYLIN_FACT",
"columnName": "DEAL_AMOUNT",
- "expression": "DEFAULT.TEST_KYLIN_FACT.PRICE * DEFAULT.TEST_KYLIN_FACT.ITEM_COUNT",
+ "expression": "PRICE * ITEM_COUNT",
"datatype": "decimal",
"comment": "deal amount of inner join model"
},
{
"tableIdentity": "DEFAULT.TEST_KYLIN_FACT",
"columnName": "DEAL_YEAR",
- "expression": "year(DEFAULT.TEST_KYLIN_FACT.CAL_DT)",
+ "expression": "year(CAL_DT)",
"datatype": "integer",
"comment": "the year of the deal of the inner join model"
},
{
"tableIdentity": "DEFAULT.TEST_ACCOUNT",
"columnName": "COUNTRY_ABBR",
- "expression": "SUBSTR(DEFAULT.TEST_ACCOUNT.ACCOUNT_COUNTRY,0,1)",
+ "expression": "SUBSTR(ACCOUNT_COUNTRY,0,1)",
"datatype": "string",
"comment": "first char of country of the inner join model"
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json b/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
index 4a10899..0058425 100644
--- a/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
+++ b/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
@@ -125,21 +125,21 @@
{
"tableIdentity": "DEFAULT.TEST_KYLIN_FACT",
"columnName": "DEAL_AMOUNT",
- "expression": "DEFAULT.TEST_KYLIN_FACT.PRICE * DEFAULT.TEST_KYLIN_FACT.ITEM_COUNT",
+ "expression": "PRICE * ITEM_COUNT",
"datatype": "decimal",
"comment": "deal amount of left join model"
},
{
"tableIdentity": "DEFAULT.TEST_KYLIN_FACT",
"columnName": "DEAL_YEAR",
- "expression": "year(DEFAULT.TEST_KYLIN_FACT.CAL_DT)",
+ "expression": "year(CAL_DT)",
"datatype": "integer",
"comment": "the year of the deal of the left join model"
},
{
"tableIdentity": "DEFAULT.TEST_ACCOUNT",
"columnName": "COUNTRY_ABBR",
- "expression": "SUBSTR(DEFAULT.TEST_ACCOUNT.ACCOUNT_COUNTRY,0,1)",
+ "expression": "SUBSTR(ACCOUNT_COUNTRY,0,1)",
"datatype": "string",
"comment": "first char of country of the left join model"
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/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 d8f1220..7f188c1 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
@@ -23,7 +23,6 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import javax.annotation.Nullable;
@@ -35,15 +34,14 @@ import org.apache.calcite.sql.SqlIntervalQualifier;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
-import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.parser.SqlParseException;
-import org.apache.calcite.sql.parser.SqlParser;
-import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.util.SqlVisitor;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.metadata.MetadataManager;
import org.apache.kylin.metadata.model.DataModelDesc;
+import org.apache.kylin.metadata.model.tool.CalciteParser;
import org.apache.kylin.metadata.project.ProjectInstance;
import org.apache.kylin.metadata.project.ProjectManager;
import org.slf4j.Logger;
@@ -65,7 +63,11 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
return sql;
}
ImmutableSortedMap<String, String> computedColumns = getSortedComputedColumnWithProject(project);
- return replaceComputedColumn(sql, computedColumns);
+ String s = replaceComputedColumn(sql, computedColumns);
+ if (!StringUtils.equals(sql, s)) {
+ logger.debug("change sql to " + s);
+ }
+ return s;
}
static String replaceComputedColumn(String inputSql, ImmutableSortedMap<String, String> computedColumn) {
@@ -88,7 +90,7 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
logger.error("Convert to computedColumn Fail,parse sql fail ", e.getMessage());
}
for (SqlNode node : matchedNodes) {
- Pair<Integer, Integer> startEndPos = getReplacePos(lines, node);
+ Pair<Integer, Integer> startEndPos = CalciteParser.getReplacePos(node, lines);
int start = startEndPos.getLeft();
int end = startEndPos.getRight();
//add table alias like t1.column,if exists alias
@@ -104,32 +106,18 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
return result;
}
- private static Pair<Integer, Integer> getReplacePos(String[] lines, SqlNode node) {
- SqlParserPos pos = node.getParserPosition();
- int lineStart = pos.getLineNum();
- int columnStart = pos.getColumnNum() - 1;
- int columnEnd = pos.getEndColumnNum();
- //for the case that sql is multi lines
- for (int i = 0; i < lineStart - 1; i++) {
- int offset = lines[i].length();
- columnStart += offset + 1;
- columnEnd += offset + 1;
- }
- return Pair.of(columnStart, columnEnd);
- }
-
//Return matched node's position and its alias(if exists).If can not find matches, return an empty capacity list
private static List<SqlNode> getMatchedNodes(String inputSql, String ccExp) throws SqlParseException {
if (ccExp == null || ccExp.equals("")) {
return new ArrayList<>();
}
ArrayList<SqlNode> toBeReplacedNodes = new ArrayList<>();
- SqlNode ccNode = getCCExpNode(ccExp);
+ SqlNode ccNode = CalciteParser.getExpNode(ccExp);
List<SqlNode> inputNodes = getInputTreeNodes(inputSql);
// find whether user input sql's tree node equals computed columns's define expression
for (SqlNode inputNode : inputNodes) {
- if (isNodeEqual(inputNode, ccNode)) {
+ if (CalciteParser.isNodeEqual(inputNode, ccNode)) {
toBeReplacedNodes.add(inputNode);
}
}
@@ -138,85 +126,10 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
private static List<SqlNode> getInputTreeNodes(String inputSql) throws SqlParseException {
SqlTreeVisitor stv = new SqlTreeVisitor();
- parse(inputSql).accept(stv);
+ CalciteParser.parse(inputSql).accept(stv);
return stv.getSqlNodes();
}
- private static SqlNode getCCExpNode(String ccExp) throws SqlParseException {
- ccExp = "select " + ccExp + " from t";
- return ((SqlSelect) parse(ccExp)).getSelectList().get(0);
- }
-
- static SqlNode parse(String sql) throws SqlParseException {
- SqlParser.ConfigBuilder parserBuilder = SqlParser.configBuilder();
- SqlParser sqlParser = SqlParser.create(sql, parserBuilder.build());
- return sqlParser.parseQuery();
- }
-
- static boolean isNodeEqual(SqlNode node0, SqlNode node1) {
- if (node0 == null) {
- return node1 == null;
- } else if (node1 == null) {
- return false;
- }
-
- if (!Objects.equals(node0.getClass().getSimpleName(), node1.getClass().getSimpleName())) {
- return false;
- }
-
- if (node0 instanceof SqlCall) {
- SqlCall thisNode = (SqlCall) node0;
- SqlCall thatNode = (SqlCall) node1;
- if (!thisNode.getOperator().getName().equalsIgnoreCase(thatNode.getOperator().getName())) {
- return false;
- }
- return isNodeEqual(thisNode.getOperandList(), thatNode.getOperandList());
- }
- if (node0 instanceof SqlLiteral) {
- SqlLiteral thisNode = (SqlLiteral) node0;
- SqlLiteral thatNode = (SqlLiteral) node1;
- return Objects.equals(thisNode.getValue(), thatNode.getValue());
- }
- if (node0 instanceof SqlNodeList) {
- SqlNodeList thisNode = (SqlNodeList) node0;
- SqlNodeList thatNode = (SqlNodeList) node1;
- if (thisNode.getList().size() != thatNode.getList().size()) {
- return false;
- }
- for (int i = 0; i < thisNode.getList().size(); i++) {
- SqlNode thisChild = thisNode.getList().get(i);
- final SqlNode thatChild = thatNode.getList().get(i);
- if (!isNodeEqual(thisChild, thatChild)) {
- return false;
- }
- }
- return true;
- }
- if (node0 instanceof SqlIdentifier) {
- SqlIdentifier thisNode = (SqlIdentifier) node0;
- SqlIdentifier thatNode = (SqlIdentifier) node1;
- // compare ignore table alias.eg: expression like "a.b + a.c + a.d" ,alias a will be ignored when compared
- String name0 = thisNode.names.get(thisNode.names.size() - 1).replace("\"", "");
- String name1 = thatNode.names.get(thatNode.names.size() - 1).replace("\"", "");
- return name0.equalsIgnoreCase(name1);
- }
-
- logger.error("Convert to computed column fail,failed to compare two nodes,unknown instance type");
- return false;
- }
-
- private static boolean isNodeEqual(List<SqlNode> operands0, List<SqlNode> operands1) {
- if (operands0.size() != operands1.size()) {
- return false;
- }
- for (int i = 0; i < operands0.size(); i++) {
- if (!isNodeEqual(operands0.get(i), operands1.get(i))) {
- return false;
- }
- }
- return true;
- }
-
private static String getTableAlias(SqlNode node) {
if (node instanceof SqlCall) {
SqlCall call = (SqlCall) node;
@@ -350,4 +263,4 @@ class SqlTreeVisitor implements SqlVisitor<SqlNode> {
public SqlNode visit(SqlIntervalQualifier intervalQualifier) {
return null;
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d61f867f/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 c3efe8d..f9b8d8b 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
@@ -21,8 +21,6 @@ package org.apache.kylin.query.util;
import java.util.HashMap;
import java.util.Map;
-import org.apache.calcite.sql.SqlNode;
-import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.parser.SqlParseException;
import org.junit.Assert;
import org.junit.Test;
@@ -30,22 +28,6 @@ import org.junit.Test;
import com.google.common.collect.ImmutableSortedMap;
public class ConvertToComputedColumnTest {
- @Test
- public void testEqual() throws SqlParseException {
- String sql0 = "select a.a + a.b + a.c from t as a";
- String sql1 = "select (((a . a + a.b + a.c))) from t as a";
- String sql2 = "select (a + b) + c from t";
- String sql3 = "select a.a + (a.b + a.c) from t as a";
-
- SqlNode sn0 = getSelectNode(sql0);
- SqlNode sn1 = getSelectNode(sql1);
- SqlNode sn2 = getSelectNode(sql2);
- SqlNode sn3 = getSelectNode(sql3);
-
- Assert.assertEquals(true, ConvertToComputedColumn.isNodeEqual(sn0, sn1));
- Assert.assertEquals(true, ConvertToComputedColumn.isNodeEqual(sn0, sn2));
- Assert.assertEquals(false, ConvertToComputedColumn.isNodeEqual(sn0, sn3));
- }
@Test
public void testErrorCase() {
@@ -101,10 +83,6 @@ public class ConvertToComputedColumnTest {
}
- private static SqlNode getSelectNode(String sql) throws SqlParseException {
- return ((SqlSelect) ConvertToComputedColumn.parse(sql)).getSelectList().get(0);
- }
-
@Test
public void testTwoCCHasSameSubExp() {
String sql0 = "select a + b + c from t order by a + b";
[13/26] kylin git commit: minor, fix bug "skip all steps after resume"
Posted by li...@apache.org.
minor, fix bug "skip all steps after resume"
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/e7f9dab7
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/e7f9dab7
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/e7f9dab7
Branch: refs/heads/kylin-2.1.x
Commit: e7f9dab77f087ce1701974abaae1b8f541448de4
Parents: 5eca7f6
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 29 23:08:27 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Thu Jun 29 23:11:00 2017 +0800
----------------------------------------------------------------------
.../kylin/job/execution/DefaultChainedExecutable.java | 1 +
.../org/apache/kylin/job/execution/ExecutableManager.java | 9 +++++++++
2 files changed, 10 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/e7f9dab7/core-job/src/main/java/org/apache/kylin/job/execution/DefaultChainedExecutable.java
----------------------------------------------------------------------
diff --git a/core-job/src/main/java/org/apache/kylin/job/execution/DefaultChainedExecutable.java b/core-job/src/main/java/org/apache/kylin/job/execution/DefaultChainedExecutable.java
index ae129ab..4f5c02b 100644
--- a/core-job/src/main/java/org/apache/kylin/job/execution/DefaultChainedExecutable.java
+++ b/core-job/src/main/java/org/apache/kylin/job/execution/DefaultChainedExecutable.java
@@ -75,6 +75,7 @@ public class DefaultChainedExecutable extends AbstractExecutable implements Chai
final long endTime = getEndTime();
if (endTime > 0) {
long interruptTime = System.currentTimeMillis() - endTime + getInterruptTime();
+ info.putAll(getManager().getJobOutput(getId()).getInfo());
info.put(START_TIME, Long.toString(startTime));
info.put(INTERRUPT_TIME, Long.toString(interruptTime));
getManager().updateJobOutput(getId(), ExecutableState.RUNNING, info, null);
http://git-wip-us.apache.org/repos/asf/kylin/blob/e7f9dab7/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
----------------------------------------------------------------------
diff --git a/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java b/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
index f16cfde..f8fb980 100644
--- a/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
+++ b/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
@@ -389,6 +389,15 @@ public class ExecutableManager {
updateJobOutput(jobId, ExecutableState.STOPPED, null, null);
}
+ public ExecutableOutputPO getJobOutput(String jobId) {
+ try {
+ return executableDao.getJobOutput(jobId);
+ } catch (PersistentException e) {
+ logger.error("Can't get output of Job " + jobId);
+ throw new RuntimeException(e);
+ }
+ }
+
public void updateJobOutput(String jobId, ExecutableState newStatus, Map<String, String> info, String output) {
try {
final ExecutableOutputPO jobOutput = executableDao.getJobOutput(jobId);
[24/26] kylin git commit: minor, rename adhoc to pushdown in KYLIN
Posted by li...@apache.org.
minor, rename adhoc to pushdown in KYLIN
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/7002dd86
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/7002dd86
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/7002dd86
Branch: refs/heads/kylin-2.1.x
Commit: 7002dd864a3f43a2e97a022d1d348773609f446d
Parents: d91f522
Author: Cheng Wang <ch...@kyligence.io>
Authored: Fri Jun 30 21:12:54 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 30 21:18:10 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/common/KylinConfigBase.java | 28 +-
.../main/resources/kylin-defaults.properties | 18 +-
.../kylin/metadata/project/ProjectManager.java | 8 +-
.../source/adhocquery/HiveAdhocConverter.java | 297 -------------------
.../adhocquery/HivePushDownConverter.java | 297 +++++++++++++++++++
.../source/adhocquery/IAdHocConverter.java | 25 --
.../kylin/source/adhocquery/IAdHocRunner.java | 39 ---
.../source/adhocquery/IPushDownConverter.java | 25 ++
.../source/adhocquery/IPushDownRunner.java | 39 +++
.../adhocquery/HiveAdhocConverterTest.java | 78 -----
.../adhocquery/HivePushDownConverterTest.java | 78 +++++
.../test_case_data/sandbox/kylin.properties | 18 +-
.../org/apache/kylin/query/KylinTestBase.java | 4 +-
.../kylin/query/adhoc/AdHocRunnerJdbcImpl.java | 122 --------
.../query/adhoc/PushDownRunnerJdbcImpl.java | 122 ++++++++
.../apache/kylin/rest/response/SQLResponse.java | 17 +-
.../apache/kylin/rest/service/QueryService.java | 150 +++++++---
.../org/apache/kylin/rest/util/AdHocUtil.java | 178 -----------
.../apache/kylin/rest/util/PushDownUtil.java | 177 +++++++++++
.../apache/kylin/rest/util/AdHocUtilTest.java | 94 ------
.../kylin/rest/util/PushDownUtilTest.java | 94 ++++++
21 files changed, 986 insertions(+), 922 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
----------------------------------------------------------------------
diff --git a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
index 4a21ded..179d61f 100644
--- a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
+++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
@@ -1022,45 +1022,45 @@ abstract public class KylinConfigBase implements Serializable {
return Integer.parseInt(this.getOptional("kylin.query.timeout-seconds", "0"));
}
- public boolean isAdhocEnabled() {
- return StringUtils.isNotEmpty(getAdHocRunnerClassName());
+ public boolean isPushDownEnabled() {
+ return StringUtils.isNotEmpty(getPushDownRunnerClassName());
}
- public String getAdHocRunnerClassName() {
- return getOptional("kylin.query.ad-hoc.runner-class-name", "");
+ public String getPushDownRunnerClassName() {
+ return getOptional("kylin.query.pushdown.runner-class-name", "");
}
- public String getAdHocConverterClassName() {
- return getOptional("kylin.query.ad-hoc.converter-class-name",
- "org.apache.kylin.source.adhocquery.HiveAdhocConverter");
+ public String getPushDownConverterClassName() {
+ return getOptional("kylin.query.pushdown.converter-class-name",
+ "org.apache.kylin.source.adhocquery.HivePushDownConverter");
}
public String getJdbcUrl() {
- return getOptional("kylin.query.ad-hoc.jdbc.url", "");
+ return getOptional("kylin.query.pushdown.jdbc.url", "");
}
public String getJdbcDriverClass() {
- return getOptional("kylin.query.ad-hoc.jdbc.driver", "");
+ return getOptional("kylin.query.pushdown.jdbc.driver", "");
}
public String getJdbcUsername() {
- return getOptional("kylin.query.ad-hoc.jdbc.username", "");
+ return getOptional("kylin.query.pushdown.jdbc.username", "");
}
public String getJdbcPassword() {
- return getOptional("kylin.query.ad-hoc.jdbc.password", "");
+ return getOptional("kylin.query.pushdown.jdbc.password", "");
}
public int getPoolMaxTotal() {
- return Integer.parseInt(this.getOptional("kylin.query.ad-hoc.jdbc.pool-max-total", "8"));
+ return Integer.parseInt(this.getOptional("kylin.query.pushdown.jdbc.pool-max-total", "8"));
}
public int getPoolMaxIdle() {
- return Integer.parseInt(this.getOptional("kylin.query.ad-hoc.jdbc.pool-max-idle", "8"));
+ return Integer.parseInt(this.getOptional("kylin.query.pushdown.jdbc.pool-max-idle", "8"));
}
public int getPoolMinIdle() {
- return Integer.parseInt(this.getOptional("kylin.query.ad-hoc.jdbc.pool-min-idle", "0"));
+ return Integer.parseInt(this.getOptional("kylin.query.pushdown.jdbc.pool-min-idle", "0"));
}
// ============================================================================
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-common/src/main/resources/kylin-defaults.properties
----------------------------------------------------------------------
diff --git a/core-common/src/main/resources/kylin-defaults.properties b/core-common/src/main/resources/kylin-defaults.properties
index beac63c..cb511e7 100644
--- a/core-common/src/main/resources/kylin-defaults.properties
+++ b/core-common/src/main/resources/kylin-defaults.properties
@@ -237,15 +237,15 @@ kylin.engine.spark-conf.spark.history.fs.logDirectory=hdfs\:///kylin/spark-histo
#kylin.engine.spark-conf.spark.executor.extraJavaOptions=-Dhdp.version=current
-### AD-HOC QUERY ###
+### QUERY PUSH DOWN ###
-#kylin.query.ad-hoc.runner-class-name=org.apache.kylin.query.adhoc.AdHocRunnerJdbcImpl
+#kylin.query.pushdown.runner-class-name=org.apache.kylin.query.adhoc.PushDownRunnerJdbcImpl
-#kylin.query.ad-hoc.jdbc.url=jdbc:hive2://sandbox:10000/default
-#kylin.query.ad-hoc.jdbc.driver=org.apache.hive.jdbc.HiveDriver
-#kylin.query.ad-hoc.jdbc.username=hive
-#kylin.query.ad-hoc.jdbc.password=
+#kylin.query.pushdown.jdbc.url=jdbc:hive2://sandbox:10000/default
+#kylin.query.pushdown.jdbc.driver=org.apache.hive.jdbc.HiveDriver
+#kylin.query.pushdown.jdbc.username=hive
+#kylin.query.pushdown.jdbc.password=
-#kylin.query.ad-hoc.jdbc.pool-max-total=8
-#kylin.query.ad-hoc.jdbc.pool-max-idle=8
-#kylin.query.ad-hoc.jdbc.pool-min-idle=0
+#kylin.query.pushdown.jdbc.pool-max-total=8
+#kylin.query.pushdown.jdbc.pool-max-idle=8
+#kylin.query.pushdown.jdbc.pool-min-idle=0
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java b/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
index ea03c3c..b801d8c 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
@@ -437,7 +437,7 @@ public class ProjectManager {
}
public Collection<TableDesc> listExposedTables(String project) {
- return config.isAdhocEnabled() ? //
+ return config.isPushDownEnabled() ? //
this.listDefinedTables(project) : //
l2Cache.listExposedTables(norm(project));
}
@@ -445,7 +445,7 @@ public class ProjectManager {
public List<ColumnDesc> listExposedColumns(String project, TableDesc tableDesc) {
Set<ColumnDesc> exposedColumns = l2Cache.listExposedColumns(norm(project), tableDesc.getIdentity());
- if (config.isAdhocEnabled()) {
+ if (config.isPushDownEnabled()) {
// take care of computed columns
Set<ColumnDesc> dedup = Sets.newHashSet(tableDesc.getColumns());
dedup.addAll(exposedColumns);
@@ -456,13 +456,13 @@ public class ProjectManager {
}
public boolean isExposedTable(String project, String table) {
- return config.isAdhocEnabled() ? //
+ return config.isPushDownEnabled() ? //
l2Cache.isDefinedTable(norm(project), table) : //
l2Cache.isExposedTable(norm(project), table);
}
public boolean isExposedColumn(String project, String table, String col) {
- return config.isAdhocEnabled() ? //
+ return config.isPushDownEnabled() ? //
l2Cache.isDefinedColumn(norm(project), table, col) || l2Cache.isExposedColumn(norm(project), table, col)
: //
l2Cache.isExposedColumn(norm(project), table, col);
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
deleted file mode 100644
index e8c06ff..0000000
--- a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * 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.kylin.source.adhocquery;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableSet;
-
-//TODO: Some workaround ways to make sql readable by hive parser, should replaced it with a more well-designed way
-public class HiveAdhocConverter implements IAdHocConverter {
-
- @SuppressWarnings("unused")
- private static final Logger logger = LoggerFactory.getLogger(HiveAdhocConverter.class);
-
- private static final Pattern EXTRACT_PATTERN = Pattern.compile("extract\\s*(\\()\\s*(.*?)\\s*from(\\s+)",
- Pattern.CASE_INSENSITIVE);
- private static final Pattern FROM_PATTERN = Pattern.compile("\\s+from\\s+(\\()\\s*select\\s",
- Pattern.CASE_INSENSITIVE);
- private static final Pattern ALIAS_PATTERN = Pattern.compile("\\s+([`'_a-z0-9A-Z]+)", Pattern.CASE_INSENSITIVE);
- private static final Pattern CAST_PATTERN = Pattern.compile("CAST\\((.*?) (?i)AS\\s*(.*?)\\s*\\)",
- Pattern.CASE_INSENSITIVE);
- private static final Pattern CONCAT_PATTERN = Pattern.compile("(['_a-z0-9A-Z]+)\\|\\|(['_a-z0-9A-Z]+)",
- Pattern.CASE_INSENSITIVE);
- private static final Pattern TIMESTAMPADD_PATTERN = Pattern.compile("timestampadd\\s*\\(\\s*(.*?)\\s*,",
- Pattern.CASE_INSENSITIVE);
- private static final ImmutableSet<String> sqlKeyWordsExceptAS = ImmutableSet.of("A", "ABS", "ABSOLUTE", "ACTION",
- "ADA", "ADD", "ADMIN", "AFTER", "ALL", "ALLOCATE", "ALLOW", "ALTER", "ALWAYS", "AND", "ANY", "APPLY", "ARE",
- "ARRAY", "ARRAY_MAX_CARDINALITY", "ASC", "ASENSITIVE", "ASSERTION", "ASSIGNMENT", "ASYMMETRIC", "AT",
- "ATOMIC", "ATTRIBUTE", "ATTRIBUTES", "AUTHORIZATION", "AVG", "BEFORE", "BEGIN", "BEGIN_FRAME",
- "BEGIN_PARTITION", "BERNOULLI", "BETWEEN", "BIGINT", "BINARY", "BIT", "BLOB", "BOOLEAN", "BOTH", "BREADTH",
- "BY", "C", "CALL", "CALLED", "CARDINALITY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG",
- "CATALOG_NAME", "CEIL", "CEILING", "CENTURY", "CHAIN", "CHAR", "CHARACTER", "CHARACTERISTICS", "CHARACTERS",
- "CHARACTER_LENGTH", "CHARACTER_SET_CATALOG", "CHARACTER_SET_NAME", "CHARACTER_SET_SCHEMA", "CHAR_LENGTH",
- "CHECK", "CLASSIFIER", "CLASS_ORIGIN", "CLOB", "CLOSE", "COALESCE", "COBOL", "COLLATE", "COLLATION",
- "COLLATION_CATALOG", "COLLATION_NAME", "COLLATION_SCHEMA", "COLLECT", "COLUMN", "COLUMN_NAME",
- "COMMAND_FUNCTION", "COMMAND_FUNCTION_CODE", "COMMIT", "COMMITTED", "CONDITION", "CONDITION_NUMBER",
- "CONNECT", "CONNECTION", "CONNECTION_NAME", "CONSTRAINT", "CONSTRAINTS", "CONSTRAINT_CATALOG",
- "CONSTRAINT_NAME", "CONSTRAINT_SCHEMA", "CONSTRUCTOR", "CONTAINS", "CONTINUE", "CONVERT", "CORR",
- "CORRESPONDING", "COUNT", "COVAR_POP", "COVAR_SAMP", "CREATE", "CROSS", "CUBE", "CUME_DIST", "CURRENT",
- "CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_DEFAULT_TRANSFORM_GROUP", "CURRENT_PATH", "CURRENT_ROLE",
- "CURRENT_ROW", "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_TRANSFORM_GROUP_FOR_TYPE",
- "CURRENT_USER", "CURSOR", "CURSOR_NAME", "CYCLE", "DATA", "DATABASE", "DATE", "DATETIME_INTERVAL_CODE",
- "DATETIME_INTERVAL_PRECISION", "DAY", "DEALLOCATE", "DEC", "DECADE", "DECIMAL", "DECLARE", "DEFAULT",
- "DEFAULTS", "DEFERRABLE", "DEFERRED", "DEFINE", "DEFINED", "DEFINER", "DEGREE", "DELETE", "DENSE_RANK",
- "DEPTH", "DEREF", "DERIVED", "DESC", "DESCRIBE", "DESCRIPTION", "DESCRIPTOR", "DETERMINISTIC",
- "DIAGNOSTICS", "DISALLOW", "DISCONNECT", "DISPATCH", "DISTINCT", "DOMAIN", "DOUBLE", "DOW", "DOY", "DROP",
- "DYNAMIC", "DYNAMIC_FUNCTION", "DYNAMIC_FUNCTION_CODE", "EACH", "ELEMENT", "ELSE", "EMPTY", "END",
- "END-EXEC", "END_FRAME", "END_PARTITION", "EPOCH", "EQUALS", "ESCAPE", "EVERY", "EXCEPT", "EXCEPTION",
- "EXCLUDE", "EXCLUDING", "EXEC", "EXECUTE", "EXISTS", "EXP", "EXPLAIN", "EXTEND", "EXTERNAL", "EXTRACT",
- "FALSE", "FETCH", "FILTER", "FINAL", "FIRST", "FIRST_VALUE", "FLOAT", "FLOOR", "FOLLOWING", "FOR",
- "FOREIGN", "FORTRAN", "FOUND", "FRAC_SECOND", "FRAME_ROW", "FREE", "FROM", "FULL", "FUNCTION", "FUSION",
- "G", "GENERAL", "GENERATED", "GET", "GLOBAL", "GO", "GOTO", "GRANT", "GRANTED", "GROUP", "GROUPING",
- "GROUPS", "HAVING", "HIERARCHY", "HOLD", "HOUR", "IDENTITY", "IMMEDIATE", "IMMEDIATELY", "IMPLEMENTATION",
- "IMPORT", "IN", "INCLUDING", "INCREMENT", "INDICATOR", "INITIAL", "INITIALLY", "INNER", "INOUT", "INPUT",
- "INSENSITIVE", "INSERT", "INSTANCE", "INSTANTIABLE", "INT", "INTEGER", "INTERSECT", "INTERSECTION",
- "INTERVAL", "INTO", "INVOKER", "IS", "ISOLATION", "JAVA", "JOIN", "JSON", "K", "KEY", "KEY_MEMBER",
- "KEY_TYPE", "LABEL", "LAG", "LANGUAGE", "LARGE", "LAST", "LAST_VALUE", "LATERAL", "LEAD", "LEADING", "LEFT",
- "LENGTH", "LEVEL", "LIBRARY", "LIKE", "LIKE_REGEX", "LIMIT", "LN", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP",
- "LOCATOR", "LOWER", "M", "MAP", "MATCH", "MATCHED", "MATCHES", "MATCH_NUMBER", "MATCH_RECOGNIZE", "MAX",
- "MAXVALUE", "MEASURES", "MEMBER", "MERGE", "MESSAGE_LENGTH", "MESSAGE_OCTET_LENGTH", "MESSAGE_TEXT",
- "METHOD", "MICROSECOND", "MILLENNIUM", "MIN", "MINUS", "MINUTE", "MINVALUE", "MOD", "MODIFIES", "MODULE",
- "MONTH", "MORE", "MULTISET", "MUMPS", "NAME", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NCLOB", "NESTING",
- "NEW", "NEXT", "NO", "NONE", "NORMALIZE", "NORMALIZED", "NOT", "NTH_VALUE", "NTILE", "NULL", "NULLABLE",
- "NULLIF", "NULLS", "NUMBER", "NUMERIC", "OBJECT", "OCCURRENCES_REGEX", "OCTETS", "OCTET_LENGTH", "OF",
- "OFFSET", "OLD", "OMIT", "ON", "ONE", "ONLY", "OPEN", "OPTION", "OPTIONS", "OR", "ORDER", "ORDERING",
- "ORDINALITY", "OTHERS", "OUT", "OUTER", "OUTPUT", "OVER", "OVERLAPS", "OVERLAY", "OVERRIDING", "PAD",
- "PARAMETER", "PARAMETER_MODE", "PARAMETER_NAME", "PARAMETER_ORDINAL_POSITION", "PARAMETER_SPECIFIC_CATALOG",
- "PARAMETER_SPECIFIC_NAME", "PARAMETER_SPECIFIC_SCHEMA", "PARTIAL", "PARTITION", "PASCAL", "PASSTHROUGH",
- "PAST", "PATH", "PATTERN", "PER", "PERCENT", "PERCENTILE_CONT", "PERCENTILE_DISC", "PERCENT_RANK", "PERIOD",
- "PERMUTE", "PLACING", "PLAN", "PLI", "PORTION", "POSITION", "POSITION_REGEX", "POWER", "PRECEDES",
- "PRECEDING", "PRECISION", "PREPARE", "PRESERVE", "PREV", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURE",
- "PUBLIC", "QUARTER", "RANGE", "RANK", "READ", "READS", "REAL", "RECURSIVE", "REF", "REFERENCES",
- "REFERENCING", "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT", "REGR_R2", "REGR_SLOPE",
- "REGR_SXX", "REGR_SXY", "REGR_SYY", "RELATIVE", "RELEASE", "REPEATABLE", "REPLACE", "RESET", "RESTART",
- "RESTRICT", "RESULT", "RETURN", "RETURNED_CARDINALITY", "RETURNED_LENGTH", "RETURNED_OCTET_LENGTH",
- "RETURNED_SQLSTATE", "RETURNS", "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROUTINE",
- "ROUTINE_CATALOG", "ROUTINE_NAME", "ROUTINE_SCHEMA", "ROW", "ROWS", "ROW_COUNT", "ROW_NUMBER", "RUNNING",
- "SAVEPOINT", "SCALE", "SCHEMA", "SCHEMA_NAME", "SCOPE", "SCOPE_CATALOGS", "SCOPE_NAME", "SCOPE_SCHEMA",
- "SCROLL", "SEARCH", "SECOND", "SECTION", "SECURITY", "SEEK", "SELECT", "SELF", "SENSITIVE", "SEQUENCE",
- "SERIALIZABLE", "SERVER", "SERVER_NAME", "SESSION", "SESSION_USER", "SET", "SETS", "SHOW", "SIMILAR",
- "SIMPLE", "SIZE", "SKIP", "SMALLINT", "SOME", "SOURCE", "SPACE", "SPECIFIC", "SPECIFICTYPE",
- "SPECIFIC_NAME", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", "SQL_BIGINT", "SQL_BINARY", "SQL_BIT",
- "SQL_BLOB", "SQL_BOOLEAN", "SQL_CHAR", "SQL_CLOB", "SQL_DATE", "SQL_DECIMAL", "SQL_DOUBLE", "SQL_FLOAT",
- "SQL_INTEGER", "SQL_INTERVAL_DAY", "SQL_INTERVAL_DAY_TO_HOUR", "SQL_INTERVAL_DAY_TO_MINUTE",
- "SQL_INTERVAL_DAY_TO_SECOND", "SQL_INTERVAL_HOUR", "SQL_INTERVAL_HOUR_TO_MINUTE",
- "SQL_INTERVAL_HOUR_TO_SECOND", "SQL_INTERVAL_MINUTE", "SQL_INTERVAL_MINUTE_TO_SECOND", "SQL_INTERVAL_MONTH",
- "SQL_INTERVAL_SECOND", "SQL_INTERVAL_YEAR", "SQL_INTERVAL_YEAR_TO_MONTH", "SQL_LONGVARBINARY",
- "SQL_LONGVARCHAR", "SQL_LONGVARNCHAR", "SQL_NCHAR", "SQL_NCLOB", "SQL_NUMERIC", "SQL_NVARCHAR", "SQL_REAL",
- "SQL_SMALLINT", "SQL_TIME", "SQL_TIMESTAMP", "SQL_TINYINT", "SQL_TSI_DAY", "SQL_TSI_FRAC_SECOND",
- "SQL_TSI_HOUR", "SQL_TSI_MICROSECOND", "SQL_TSI_MINUTE", "SQL_TSI_MONTH", "SQL_TSI_QUARTER",
- "SQL_TSI_SECOND", "SQL_TSI_WEEK", "SQL_TSI_YEAR", "SQL_VARBINARY", "SQL_VARCHAR", "SQRT", "START", "STATE",
- "STATEMENT", "STATIC", "STDDEV_POP", "STDDEV_SAMP", "STREAM", "STRUCTURE", "STYLE", "SUBCLASS_ORIGIN",
- "SUBMULTISET", "SUBSET", "SUBSTITUTE", "SUBSTRING", "SUBSTRING_REGEX", "SUCCEEDS", "SUM", "SYMMETRIC",
- "SYSTEM", "SYSTEM_TIME", "SYSTEM_USER", "TABLE", "TABLESAMPLE", "TABLE_NAME", "TEMPORARY", "THEN", "TIES",
- "TIME", "TIMESTAMP", "TIMESTAMPADD", "TIMESTAMPDIFF", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TINYINT", "TO",
- "TOP_LEVEL_COUNT", "TRAILING", "TRANSACTION", "TRANSACTIONS_ACTIVE", "TRANSACTIONS_COMMITTED",
- "TRANSACTIONS_ROLLED_BACK", "TRANSFORM", "TRANSFORMS", "TRANSLATE", "TRANSLATE_REGEX", "TRANSLATION",
- "TREAT", "TRIGGER", "TRIGGER_CATALOG", "TRIGGER_NAME", "TRIGGER_SCHEMA", "TRIM", "TRIM_ARRAY", "TRUE",
- "TRUNCATE", "TYPE", "UESCAPE", "UNBOUNDED", "UNCOMMITTED", "UNDER", "UNION", "UNIQUE", "UNKNOWN", "UNNAMED",
- "UNNEST", "UPDATE", "UPPER", "UPSERT", "USAGE", "USER", "USER_DEFINED_TYPE_CATALOG",
- "USER_DEFINED_TYPE_CODE", "USER_DEFINED_TYPE_NAME", "USER_DEFINED_TYPE_SCHEMA", "USING", "VALUE", "VALUES",
- "VALUE_OF", "VARBINARY", "VARCHAR", "VARYING", "VAR_POP", "VAR_SAMP", "VERSION", "VERSIONING", "VIEW",
- "WEEK", "WHEN", "WHENEVER", "WHERE", "WIDTH_BUCKET", "WINDOW", "WITH", "WITHIN", "WITHOUT", "WORK",
- "WRAPPER", "WRITE", "XML", "YEAR", "ZONE");
-
- public static String replaceString(String originString, String fromString, String toString) {
- return originString.replace(fromString, toString);
- }
-
- public static String extractReplace(String originString) {
- Matcher extractMatcher = EXTRACT_PATTERN.matcher(originString);
- String replacedString = originString;
- Map<Integer, Integer> parenthesesPairs = null;
-
- while (extractMatcher.find()) {
- if (parenthesesPairs == null) {
- parenthesesPairs = findParenthesesPairs(originString);
- }
-
- String functionStr = extractMatcher.group(2);
- int startIdx = extractMatcher.end(3);
- int endIdx = parenthesesPairs.get(extractMatcher.start(1));
- String extractInner = originString.substring(startIdx, endIdx);
- int originStart = extractMatcher.start(0);
- int originEnd = endIdx + 1;
-
- replacedString = replaceString(replacedString, originString.substring(originStart, originEnd),
- functionStr + "(" + extractInner + ")");
- }
-
- return replacedString;
- }
-
- public static String castReplace(String originString) {
- Matcher castMatcher = CAST_PATTERN.matcher(originString);
- String replacedString = originString;
-
- while (castMatcher.find()) {
- String castStr = castMatcher.group();
- String type = castMatcher.group(2);
- String supportedType = "";
- switch (type.toUpperCase()) {
- case "INTEGER":
- supportedType = "int";
- break;
- case "SHORT":
- supportedType = "smallint";
- break;
- case "LONG":
- supportedType = "bigint";
- break;
- default:
- supportedType = type;
- }
-
- if (!supportedType.equals(type)) {
- String replacedCastStr = castStr.replace(type, supportedType);
- replacedString = replaceString(replacedString, castStr, replacedCastStr);
- }
- }
-
- return replacedString;
- }
-
- public static String subqueryReplace(String originString) {
- Matcher subqueryMatcher = FROM_PATTERN.matcher(originString);
- String replacedString = originString;
- Map<Integer, Integer> parenthesesPairs = null;
-
- while (subqueryMatcher.find()) {
- if (parenthesesPairs == null) {
- parenthesesPairs = findParenthesesPairs(originString);
- }
-
- int startIdx = subqueryMatcher.start(1);
- int endIdx = parenthesesPairs.get(startIdx) + 1;
-
- Matcher aliasMatcher = ALIAS_PATTERN.matcher(originString.substring(endIdx));
- if (aliasMatcher.find()) {
- String aliasCandidate = aliasMatcher.group(1);
-
- if (aliasCandidate != null && !sqlKeyWordsExceptAS.contains(aliasCandidate.toUpperCase())) {
- continue;
- }
-
- replacedString = replaceString(replacedString, originString.substring(startIdx, endIdx),
- originString.substring(startIdx, endIdx) + " as alias");
- }
- }
-
- return replacedString;
- }
-
- public static String timestampaddReplace(String originString) {
- Matcher timestampaddMatcher = TIMESTAMPADD_PATTERN.matcher(originString);
- String replacedString = originString;
-
- while (timestampaddMatcher.find()) {
- String interval = timestampaddMatcher.group(1);
- String timestampaddStr = replaceString(timestampaddMatcher.group(), interval, "'" + interval + "'");
- replacedString = replaceString(replacedString, timestampaddMatcher.group(), timestampaddStr);
- }
-
- return replacedString;
- }
-
- public static String concatReplace(String originString) {
- Matcher concatMatcher = CONCAT_PATTERN.matcher(originString);
- String replacedString = originString;
-
- while (concatMatcher.find()) {
- String leftString = concatMatcher.group(1);
- String rightString = concatMatcher.group(2);
- replacedString = replaceString(replacedString, leftString + "||" + rightString,
- "concat(" + leftString + "," + rightString + ")");
- }
-
- return replacedString;
- }
-
- public static String doConvert(String originStr) {
- // Step1.Replace " with `
- String convertedSql = replaceString(originStr, "\"", "`");
-
- // Step2.Replace extract functions
- convertedSql = extractReplace(convertedSql);
-
- // Step3.Replace cast type string
- convertedSql = castReplace(convertedSql);
-
- // Step4.Replace sub query
- convertedSql = subqueryReplace(convertedSql);
-
- // Step5.Replace char_length with length
- convertedSql = replaceString(convertedSql, "char_length", "length");
-
- // Step6.Replace "||" with concat
- convertedSql = concatReplace(convertedSql);
-
- // Step7.Add quote for interval in timestampadd
- convertedSql = timestampaddReplace(convertedSql);
-
- return convertedSql;
- }
-
- private static Map<Integer, Integer> findParenthesesPairs(String sql) {
- Map<Integer, Integer> result = new HashMap<>();
- if (sql.length() > 1) {
- Stack<Integer> lStack = new Stack<>();
- boolean inStrVal = false;
- for (int i = 0; i < sql.length(); i++) {
- switch (sql.charAt(i)) {
- case '(':
- if (!inStrVal) {
- lStack.push(i);
- }
- break;
- case ')':
- if (!inStrVal && !lStack.empty()) {
- result.put(lStack.pop(), i);
- }
- break;
- default:
- break;
- }
- }
- }
- return result;
- }
-
- @Override
- public String convert(String originSql) {
- return doConvert(originSql);
- }
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HivePushDownConverter.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HivePushDownConverter.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HivePushDownConverter.java
new file mode 100644
index 0000000..8d89294
--- /dev/null
+++ b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HivePushDownConverter.java
@@ -0,0 +1,297 @@
+/*
+ * 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.kylin.source.adhocquery;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSet;
+
+//TODO: Some workaround ways to make sql readable by hive parser, should replaced it with a more well-designed way
+public class HivePushDownConverter implements IPushDownConverter {
+
+ @SuppressWarnings("unused")
+ private static final Logger logger = LoggerFactory.getLogger(HivePushDownConverter.class);
+
+ private static final Pattern EXTRACT_PATTERN = Pattern.compile("extract\\s*(\\()\\s*(.*?)\\s*from(\\s+)",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern FROM_PATTERN = Pattern.compile("\\s+from\\s+(\\()\\s*select\\s",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern ALIAS_PATTERN = Pattern.compile("\\s+([`'_a-z0-9A-Z]+)", Pattern.CASE_INSENSITIVE);
+ private static final Pattern CAST_PATTERN = Pattern.compile("CAST\\((.*?) (?i)AS\\s*(.*?)\\s*\\)",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern CONCAT_PATTERN = Pattern.compile("(['_a-z0-9A-Z]+)\\|\\|(['_a-z0-9A-Z]+)",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern TIMESTAMPADD_PATTERN = Pattern.compile("timestampadd\\s*\\(\\s*(.*?)\\s*,",
+ Pattern.CASE_INSENSITIVE);
+ private static final ImmutableSet<String> sqlKeyWordsExceptAS = ImmutableSet.of("A", "ABS", "ABSOLUTE", "ACTION",
+ "ADA", "ADD", "ADMIN", "AFTER", "ALL", "ALLOCATE", "ALLOW", "ALTER", "ALWAYS", "AND", "ANY", "APPLY", "ARE",
+ "ARRAY", "ARRAY_MAX_CARDINALITY", "ASC", "ASENSITIVE", "ASSERTION", "ASSIGNMENT", "ASYMMETRIC", "AT",
+ "ATOMIC", "ATTRIBUTE", "ATTRIBUTES", "AUTHORIZATION", "AVG", "BEFORE", "BEGIN", "BEGIN_FRAME",
+ "BEGIN_PARTITION", "BERNOULLI", "BETWEEN", "BIGINT", "BINARY", "BIT", "BLOB", "BOOLEAN", "BOTH", "BREADTH",
+ "BY", "C", "CALL", "CALLED", "CARDINALITY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG",
+ "CATALOG_NAME", "CEIL", "CEILING", "CENTURY", "CHAIN", "CHAR", "CHARACTER", "CHARACTERISTICS", "CHARACTERS",
+ "CHARACTER_LENGTH", "CHARACTER_SET_CATALOG", "CHARACTER_SET_NAME", "CHARACTER_SET_SCHEMA", "CHAR_LENGTH",
+ "CHECK", "CLASSIFIER", "CLASS_ORIGIN", "CLOB", "CLOSE", "COALESCE", "COBOL", "COLLATE", "COLLATION",
+ "COLLATION_CATALOG", "COLLATION_NAME", "COLLATION_SCHEMA", "COLLECT", "COLUMN", "COLUMN_NAME",
+ "COMMAND_FUNCTION", "COMMAND_FUNCTION_CODE", "COMMIT", "COMMITTED", "CONDITION", "CONDITION_NUMBER",
+ "CONNECT", "CONNECTION", "CONNECTION_NAME", "CONSTRAINT", "CONSTRAINTS", "CONSTRAINT_CATALOG",
+ "CONSTRAINT_NAME", "CONSTRAINT_SCHEMA", "CONSTRUCTOR", "CONTAINS", "CONTINUE", "CONVERT", "CORR",
+ "CORRESPONDING", "COUNT", "COVAR_POP", "COVAR_SAMP", "CREATE", "CROSS", "CUBE", "CUME_DIST", "CURRENT",
+ "CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_DEFAULT_TRANSFORM_GROUP", "CURRENT_PATH", "CURRENT_ROLE",
+ "CURRENT_ROW", "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_TRANSFORM_GROUP_FOR_TYPE",
+ "CURRENT_USER", "CURSOR", "CURSOR_NAME", "CYCLE", "DATA", "DATABASE", "DATE", "DATETIME_INTERVAL_CODE",
+ "DATETIME_INTERVAL_PRECISION", "DAY", "DEALLOCATE", "DEC", "DECADE", "DECIMAL", "DECLARE", "DEFAULT",
+ "DEFAULTS", "DEFERRABLE", "DEFERRED", "DEFINE", "DEFINED", "DEFINER", "DEGREE", "DELETE", "DENSE_RANK",
+ "DEPTH", "DEREF", "DERIVED", "DESC", "DESCRIBE", "DESCRIPTION", "DESCRIPTOR", "DETERMINISTIC",
+ "DIAGNOSTICS", "DISALLOW", "DISCONNECT", "DISPATCH", "DISTINCT", "DOMAIN", "DOUBLE", "DOW", "DOY", "DROP",
+ "DYNAMIC", "DYNAMIC_FUNCTION", "DYNAMIC_FUNCTION_CODE", "EACH", "ELEMENT", "ELSE", "EMPTY", "END",
+ "END-EXEC", "END_FRAME", "END_PARTITION", "EPOCH", "EQUALS", "ESCAPE", "EVERY", "EXCEPT", "EXCEPTION",
+ "EXCLUDE", "EXCLUDING", "EXEC", "EXECUTE", "EXISTS", "EXP", "EXPLAIN", "EXTEND", "EXTERNAL", "EXTRACT",
+ "FALSE", "FETCH", "FILTER", "FINAL", "FIRST", "FIRST_VALUE", "FLOAT", "FLOOR", "FOLLOWING", "FOR",
+ "FOREIGN", "FORTRAN", "FOUND", "FRAC_SECOND", "FRAME_ROW", "FREE", "FROM", "FULL", "FUNCTION", "FUSION",
+ "G", "GENERAL", "GENERATED", "GET", "GLOBAL", "GO", "GOTO", "GRANT", "GRANTED", "GROUP", "GROUPING",
+ "GROUPS", "HAVING", "HIERARCHY", "HOLD", "HOUR", "IDENTITY", "IMMEDIATE", "IMMEDIATELY", "IMPLEMENTATION",
+ "IMPORT", "IN", "INCLUDING", "INCREMENT", "INDICATOR", "INITIAL", "INITIALLY", "INNER", "INOUT", "INPUT",
+ "INSENSITIVE", "INSERT", "INSTANCE", "INSTANTIABLE", "INT", "INTEGER", "INTERSECT", "INTERSECTION",
+ "INTERVAL", "INTO", "INVOKER", "IS", "ISOLATION", "JAVA", "JOIN", "JSON", "K", "KEY", "KEY_MEMBER",
+ "KEY_TYPE", "LABEL", "LAG", "LANGUAGE", "LARGE", "LAST", "LAST_VALUE", "LATERAL", "LEAD", "LEADING", "LEFT",
+ "LENGTH", "LEVEL", "LIBRARY", "LIKE", "LIKE_REGEX", "LIMIT", "LN", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP",
+ "LOCATOR", "LOWER", "M", "MAP", "MATCH", "MATCHED", "MATCHES", "MATCH_NUMBER", "MATCH_RECOGNIZE", "MAX",
+ "MAXVALUE", "MEASURES", "MEMBER", "MERGE", "MESSAGE_LENGTH", "MESSAGE_OCTET_LENGTH", "MESSAGE_TEXT",
+ "METHOD", "MICROSECOND", "MILLENNIUM", "MIN", "MINUS", "MINUTE", "MINVALUE", "MOD", "MODIFIES", "MODULE",
+ "MONTH", "MORE", "MULTISET", "MUMPS", "NAME", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NCLOB", "NESTING",
+ "NEW", "NEXT", "NO", "NONE", "NORMALIZE", "NORMALIZED", "NOT", "NTH_VALUE", "NTILE", "NULL", "NULLABLE",
+ "NULLIF", "NULLS", "NUMBER", "NUMERIC", "OBJECT", "OCCURRENCES_REGEX", "OCTETS", "OCTET_LENGTH", "OF",
+ "OFFSET", "OLD", "OMIT", "ON", "ONE", "ONLY", "OPEN", "OPTION", "OPTIONS", "OR", "ORDER", "ORDERING",
+ "ORDINALITY", "OTHERS", "OUT", "OUTER", "OUTPUT", "OVER", "OVERLAPS", "OVERLAY", "OVERRIDING", "PAD",
+ "PARAMETER", "PARAMETER_MODE", "PARAMETER_NAME", "PARAMETER_ORDINAL_POSITION", "PARAMETER_SPECIFIC_CATALOG",
+ "PARAMETER_SPECIFIC_NAME", "PARAMETER_SPECIFIC_SCHEMA", "PARTIAL", "PARTITION", "PASCAL", "PASSTHROUGH",
+ "PAST", "PATH", "PATTERN", "PER", "PERCENT", "PERCENTILE_CONT", "PERCENTILE_DISC", "PERCENT_RANK", "PERIOD",
+ "PERMUTE", "PLACING", "PLAN", "PLI", "PORTION", "POSITION", "POSITION_REGEX", "POWER", "PRECEDES",
+ "PRECEDING", "PRECISION", "PREPARE", "PRESERVE", "PREV", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURE",
+ "PUBLIC", "QUARTER", "RANGE", "RANK", "READ", "READS", "REAL", "RECURSIVE", "REF", "REFERENCES",
+ "REFERENCING", "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT", "REGR_R2", "REGR_SLOPE",
+ "REGR_SXX", "REGR_SXY", "REGR_SYY", "RELATIVE", "RELEASE", "REPEATABLE", "REPLACE", "RESET", "RESTART",
+ "RESTRICT", "RESULT", "RETURN", "RETURNED_CARDINALITY", "RETURNED_LENGTH", "RETURNED_OCTET_LENGTH",
+ "RETURNED_SQLSTATE", "RETURNS", "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROUTINE",
+ "ROUTINE_CATALOG", "ROUTINE_NAME", "ROUTINE_SCHEMA", "ROW", "ROWS", "ROW_COUNT", "ROW_NUMBER", "RUNNING",
+ "SAVEPOINT", "SCALE", "SCHEMA", "SCHEMA_NAME", "SCOPE", "SCOPE_CATALOGS", "SCOPE_NAME", "SCOPE_SCHEMA",
+ "SCROLL", "SEARCH", "SECOND", "SECTION", "SECURITY", "SEEK", "SELECT", "SELF", "SENSITIVE", "SEQUENCE",
+ "SERIALIZABLE", "SERVER", "SERVER_NAME", "SESSION", "SESSION_USER", "SET", "SETS", "SHOW", "SIMILAR",
+ "SIMPLE", "SIZE", "SKIP", "SMALLINT", "SOME", "SOURCE", "SPACE", "SPECIFIC", "SPECIFICTYPE",
+ "SPECIFIC_NAME", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", "SQL_BIGINT", "SQL_BINARY", "SQL_BIT",
+ "SQL_BLOB", "SQL_BOOLEAN", "SQL_CHAR", "SQL_CLOB", "SQL_DATE", "SQL_DECIMAL", "SQL_DOUBLE", "SQL_FLOAT",
+ "SQL_INTEGER", "SQL_INTERVAL_DAY", "SQL_INTERVAL_DAY_TO_HOUR", "SQL_INTERVAL_DAY_TO_MINUTE",
+ "SQL_INTERVAL_DAY_TO_SECOND", "SQL_INTERVAL_HOUR", "SQL_INTERVAL_HOUR_TO_MINUTE",
+ "SQL_INTERVAL_HOUR_TO_SECOND", "SQL_INTERVAL_MINUTE", "SQL_INTERVAL_MINUTE_TO_SECOND", "SQL_INTERVAL_MONTH",
+ "SQL_INTERVAL_SECOND", "SQL_INTERVAL_YEAR", "SQL_INTERVAL_YEAR_TO_MONTH", "SQL_LONGVARBINARY",
+ "SQL_LONGVARCHAR", "SQL_LONGVARNCHAR", "SQL_NCHAR", "SQL_NCLOB", "SQL_NUMERIC", "SQL_NVARCHAR", "SQL_REAL",
+ "SQL_SMALLINT", "SQL_TIME", "SQL_TIMESTAMP", "SQL_TINYINT", "SQL_TSI_DAY", "SQL_TSI_FRAC_SECOND",
+ "SQL_TSI_HOUR", "SQL_TSI_MICROSECOND", "SQL_TSI_MINUTE", "SQL_TSI_MONTH", "SQL_TSI_QUARTER",
+ "SQL_TSI_SECOND", "SQL_TSI_WEEK", "SQL_TSI_YEAR", "SQL_VARBINARY", "SQL_VARCHAR", "SQRT", "START", "STATE",
+ "STATEMENT", "STATIC", "STDDEV_POP", "STDDEV_SAMP", "STREAM", "STRUCTURE", "STYLE", "SUBCLASS_ORIGIN",
+ "SUBMULTISET", "SUBSET", "SUBSTITUTE", "SUBSTRING", "SUBSTRING_REGEX", "SUCCEEDS", "SUM", "SYMMETRIC",
+ "SYSTEM", "SYSTEM_TIME", "SYSTEM_USER", "TABLE", "TABLESAMPLE", "TABLE_NAME", "TEMPORARY", "THEN", "TIES",
+ "TIME", "TIMESTAMP", "TIMESTAMPADD", "TIMESTAMPDIFF", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TINYINT", "TO",
+ "TOP_LEVEL_COUNT", "TRAILING", "TRANSACTION", "TRANSACTIONS_ACTIVE", "TRANSACTIONS_COMMITTED",
+ "TRANSACTIONS_ROLLED_BACK", "TRANSFORM", "TRANSFORMS", "TRANSLATE", "TRANSLATE_REGEX", "TRANSLATION",
+ "TREAT", "TRIGGER", "TRIGGER_CATALOG", "TRIGGER_NAME", "TRIGGER_SCHEMA", "TRIM", "TRIM_ARRAY", "TRUE",
+ "TRUNCATE", "TYPE", "UESCAPE", "UNBOUNDED", "UNCOMMITTED", "UNDER", "UNION", "UNIQUE", "UNKNOWN", "UNNAMED",
+ "UNNEST", "UPDATE", "UPPER", "UPSERT", "USAGE", "USER", "USER_DEFINED_TYPE_CATALOG",
+ "USER_DEFINED_TYPE_CODE", "USER_DEFINED_TYPE_NAME", "USER_DEFINED_TYPE_SCHEMA", "USING", "VALUE", "VALUES",
+ "VALUE_OF", "VARBINARY", "VARCHAR", "VARYING", "VAR_POP", "VAR_SAMP", "VERSION", "VERSIONING", "VIEW",
+ "WEEK", "WHEN", "WHENEVER", "WHERE", "WIDTH_BUCKET", "WINDOW", "WITH", "WITHIN", "WITHOUT", "WORK",
+ "WRAPPER", "WRITE", "XML", "YEAR", "ZONE");
+
+ public static String replaceString(String originString, String fromString, String toString) {
+ return originString.replace(fromString, toString);
+ }
+
+ public static String extractReplace(String originString) {
+ Matcher extractMatcher = EXTRACT_PATTERN.matcher(originString);
+ String replacedString = originString;
+ Map<Integer, Integer> parenthesesPairs = null;
+
+ while (extractMatcher.find()) {
+ if (parenthesesPairs == null) {
+ parenthesesPairs = findParenthesesPairs(originString);
+ }
+
+ String functionStr = extractMatcher.group(2);
+ int startIdx = extractMatcher.end(3);
+ int endIdx = parenthesesPairs.get(extractMatcher.start(1));
+ String extractInner = originString.substring(startIdx, endIdx);
+ int originStart = extractMatcher.start(0);
+ int originEnd = endIdx + 1;
+
+ replacedString = replaceString(replacedString, originString.substring(originStart, originEnd),
+ functionStr + "(" + extractInner + ")");
+ }
+
+ return replacedString;
+ }
+
+ public static String castReplace(String originString) {
+ Matcher castMatcher = CAST_PATTERN.matcher(originString);
+ String replacedString = originString;
+
+ while (castMatcher.find()) {
+ String castStr = castMatcher.group();
+ String type = castMatcher.group(2);
+ String supportedType = "";
+ switch (type.toUpperCase()) {
+ case "INTEGER":
+ supportedType = "int";
+ break;
+ case "SHORT":
+ supportedType = "smallint";
+ break;
+ case "LONG":
+ supportedType = "bigint";
+ break;
+ default:
+ supportedType = type;
+ }
+
+ if (!supportedType.equals(type)) {
+ String replacedCastStr = castStr.replace(type, supportedType);
+ replacedString = replaceString(replacedString, castStr, replacedCastStr);
+ }
+ }
+
+ return replacedString;
+ }
+
+ public static String subqueryReplace(String originString) {
+ Matcher subqueryMatcher = FROM_PATTERN.matcher(originString);
+ String replacedString = originString;
+ Map<Integer, Integer> parenthesesPairs = null;
+
+ while (subqueryMatcher.find()) {
+ if (parenthesesPairs == null) {
+ parenthesesPairs = findParenthesesPairs(originString);
+ }
+
+ int startIdx = subqueryMatcher.start(1);
+ int endIdx = parenthesesPairs.get(startIdx) + 1;
+
+ Matcher aliasMatcher = ALIAS_PATTERN.matcher(originString.substring(endIdx));
+ if (aliasMatcher.find()) {
+ String aliasCandidate = aliasMatcher.group(1);
+
+ if (aliasCandidate != null && !sqlKeyWordsExceptAS.contains(aliasCandidate.toUpperCase())) {
+ continue;
+ }
+
+ replacedString = replaceString(replacedString, originString.substring(startIdx, endIdx),
+ originString.substring(startIdx, endIdx) + " as alias");
+ }
+ }
+
+ return replacedString;
+ }
+
+ public static String timestampaddReplace(String originString) {
+ Matcher timestampaddMatcher = TIMESTAMPADD_PATTERN.matcher(originString);
+ String replacedString = originString;
+
+ while (timestampaddMatcher.find()) {
+ String interval = timestampaddMatcher.group(1);
+ String timestampaddStr = replaceString(timestampaddMatcher.group(), interval, "'" + interval + "'");
+ replacedString = replaceString(replacedString, timestampaddMatcher.group(), timestampaddStr);
+ }
+
+ return replacedString;
+ }
+
+ public static String concatReplace(String originString) {
+ Matcher concatMatcher = CONCAT_PATTERN.matcher(originString);
+ String replacedString = originString;
+
+ while (concatMatcher.find()) {
+ String leftString = concatMatcher.group(1);
+ String rightString = concatMatcher.group(2);
+ replacedString = replaceString(replacedString, leftString + "||" + rightString,
+ "concat(" + leftString + "," + rightString + ")");
+ }
+
+ return replacedString;
+ }
+
+ public static String doConvert(String originStr) {
+ // Step1.Replace " with `
+ String convertedSql = replaceString(originStr, "\"", "`");
+
+ // Step2.Replace extract functions
+ convertedSql = extractReplace(convertedSql);
+
+ // Step3.Replace cast type string
+ convertedSql = castReplace(convertedSql);
+
+ // Step4.Replace sub query
+ convertedSql = subqueryReplace(convertedSql);
+
+ // Step5.Replace char_length with length
+ convertedSql = replaceString(convertedSql, "char_length", "length");
+
+ // Step6.Replace "||" with concat
+ convertedSql = concatReplace(convertedSql);
+
+ // Step7.Add quote for interval in timestampadd
+ convertedSql = timestampaddReplace(convertedSql);
+
+ return convertedSql;
+ }
+
+ private static Map<Integer, Integer> findParenthesesPairs(String sql) {
+ Map<Integer, Integer> result = new HashMap<>();
+ if (sql.length() > 1) {
+ Stack<Integer> lStack = new Stack<>();
+ boolean inStrVal = false;
+ for (int i = 0; i < sql.length(); i++) {
+ switch (sql.charAt(i)) {
+ case '(':
+ if (!inStrVal) {
+ lStack.push(i);
+ }
+ break;
+ case ')':
+ if (!inStrVal && !lStack.empty()) {
+ result.put(lStack.pop(), i);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public String convert(String originSql) {
+ return doConvert(originSql);
+ }
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocConverter.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocConverter.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocConverter.java
deleted file mode 100644
index c4b87f8..0000000
--- a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocConverter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.kylin.source.adhocquery;
-
-/**
- * convert the query to satisfy the parser of adhoc query engine
- */
-public interface IAdHocConverter {
- String convert(String originSql);
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocRunner.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocRunner.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocRunner.java
deleted file mode 100644
index 369325c..0000000
--- a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocRunner.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.kylin.source.adhocquery;
-
-import java.util.List;
-
-import org.apache.kylin.common.KylinConfig;
-import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
-
-public interface IAdHocRunner {
-
- void init(KylinConfig config);
-
- /**
- * Run an ad-hoc query in the source database in case Kylin cannot serve using cube.
- *
- * @param query the query statement
- * @param returnRows an empty list to collect returning rows
- * @param returnColumnMeta an empty list to collect metadata of returning columns
- * @throws Exception if running ad-hoc query fails
- */
- void executeQuery(String query, List<List<String>> returnRows, List<SelectedColumnMeta> returnColumnMeta) throws Exception;
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownConverter.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownConverter.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownConverter.java
new file mode 100644
index 0000000..c4e7515
--- /dev/null
+++ b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownConverter.java
@@ -0,0 +1,25 @@
+/*
+ * 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.kylin.source.adhocquery;
+
+/**
+ * convert the query to satisfy the parser of push down query engine
+ */
+public interface IPushDownConverter {
+ String convert(String originSql);
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownRunner.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownRunner.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownRunner.java
new file mode 100644
index 0000000..c8d18aa
--- /dev/null
+++ b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IPushDownRunner.java
@@ -0,0 +1,39 @@
+/*
+ * 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.kylin.source.adhocquery;
+
+import java.util.List;
+
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
+
+public interface IPushDownRunner {
+
+ void init(KylinConfig config);
+
+ /**
+ * Run an pushdown query in the source database in case Kylin cannot serve using cube.
+ *
+ * @param query the query statement
+ * @param returnRows an empty list to collect returning rows
+ * @param returnColumnMeta an empty list to collect metadata of returning columns
+ * @throws Exception if running pushdown query fails
+ */
+ void executeQuery(String query, List<List<String>> returnRows, List<SelectedColumnMeta> returnColumnMeta) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java b/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
deleted file mode 100644
index cfb0f32..0000000
--- a/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.kylin.source.adhocquery;
-
-import org.junit.Test;
-
-import junit.framework.TestCase;
-
-public class HiveAdhocConverterTest extends TestCase {
- @Test
- public void testStringReplace() {
- String originString = "select count(*) as cnt from test_kylin_fact where char_length(lstg_format_name) < 10";
- String replacedString = HiveAdhocConverter.replaceString(originString, "char_length", "length");
- assertEquals("select count(*) as cnt from test_kylin_fact where length(lstg_format_name) < 10", replacedString);
- }
-
- @Test
- public void testExtractReplace() {
- String originString = "ignore EXTRACT(YEAR FROM KYLIN_CAL_DT.CAL_DT) ignore";
- String replacedString = HiveAdhocConverter.extractReplace(originString);
- assertEquals("ignore YEAR(KYLIN_CAL_DT.CAL_DT) ignore", replacedString);
- }
-
- @Test
- public void testCastReplace() {
- String originString = "ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS INTEGER)) ignore";
- String replacedString = HiveAdhocConverter.castReplace(originString);
- assertEquals("ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS int)) ignore", replacedString);
- }
-
- @Test
- public void testSubqueryReplace1() {
- String originString = "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) group by seller_id,lstg_format_name";
- String replacedString = HiveAdhocConverter.subqueryReplace(originString);
- assertEquals(
- "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) as alias group by seller_id,lstg_format_name",
- replacedString);
- }
-
- @Test
- public void testSubqueryReplace2() {
- String originString = "select count(*) from ( select test_kylin_fact.lstg_format_name from test_kylin_fact where test_kylin_fact.lstg_format_name='FP-GTC' group by test_kylin_fact.lstg_format_name ) t ";
- String replacedString = HiveAdhocConverter.subqueryReplace(originString);
- assertEquals(originString, replacedString);
- }
-
- @Test
- public void testSubqueryReplace3() {
- String originString = "select fact.lstg_format_name from (select * from test_kylin_fact where cal_dt > date'2010-01-01' ) as fact group by fact.lstg_format_name order by CASE WHEN fact.lstg_format_name IS NULL THEN 'sdf' ELSE fact.lstg_format_name END ";
- String replacedString = HiveAdhocConverter.subqueryReplace(originString);
- assertEquals(originString, replacedString);
- }
-
- @Test
- public void testConcatReplace() {
- String originString = "select count(*) as cnt from test_kylin_fact where lstg_format_name||'a'='ABINa'";
- String replacedString = HiveAdhocConverter.concatReplace(originString);
- assertEquals("select count(*) as cnt from test_kylin_fact where concat(lstg_format_name,'a')='ABINa'",
- replacedString);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HivePushDownConverterTest.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HivePushDownConverterTest.java b/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HivePushDownConverterTest.java
new file mode 100644
index 0000000..42c628a
--- /dev/null
+++ b/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HivePushDownConverterTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.kylin.source.adhocquery;
+
+import org.junit.Test;
+
+import junit.framework.TestCase;
+
+public class HivePushDownConverterTest extends TestCase {
+ @Test
+ public void testStringReplace() {
+ String originString = "select count(*) as cnt from test_kylin_fact where char_length(lstg_format_name) < 10";
+ String replacedString = HivePushDownConverter.replaceString(originString, "char_length", "length");
+ assertEquals("select count(*) as cnt from test_kylin_fact where length(lstg_format_name) < 10", replacedString);
+ }
+
+ @Test
+ public void testExtractReplace() {
+ String originString = "ignore EXTRACT(YEAR FROM KYLIN_CAL_DT.CAL_DT) ignore";
+ String replacedString = HivePushDownConverter.extractReplace(originString);
+ assertEquals("ignore YEAR(KYLIN_CAL_DT.CAL_DT) ignore", replacedString);
+ }
+
+ @Test
+ public void testCastReplace() {
+ String originString = "ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS INTEGER)) ignore";
+ String replacedString = HivePushDownConverter.castReplace(originString);
+ assertEquals("ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS int)) ignore", replacedString);
+ }
+
+ @Test
+ public void testSubqueryReplace1() {
+ String originString = "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) group by seller_id,lstg_format_name";
+ String replacedString = HivePushDownConverter.subqueryReplace(originString);
+ assertEquals(
+ "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) as alias group by seller_id,lstg_format_name",
+ replacedString);
+ }
+
+ @Test
+ public void testSubqueryReplace2() {
+ String originString = "select count(*) from ( select test_kylin_fact.lstg_format_name from test_kylin_fact where test_kylin_fact.lstg_format_name='FP-GTC' group by test_kylin_fact.lstg_format_name ) t ";
+ String replacedString = HivePushDownConverter.subqueryReplace(originString);
+ assertEquals(originString, replacedString);
+ }
+
+ @Test
+ public void testSubqueryReplace3() {
+ String originString = "select fact.lstg_format_name from (select * from test_kylin_fact where cal_dt > date'2010-01-01' ) as fact group by fact.lstg_format_name order by CASE WHEN fact.lstg_format_name IS NULL THEN 'sdf' ELSE fact.lstg_format_name END ";
+ String replacedString = HivePushDownConverter.subqueryReplace(originString);
+ assertEquals(originString, replacedString);
+ }
+
+ @Test
+ public void testConcatReplace() {
+ String originString = "select count(*) as cnt from test_kylin_fact where lstg_format_name||'a'='ABINa'";
+ String replacedString = HivePushDownConverter.concatReplace(originString);
+ assertEquals("select count(*) as cnt from test_kylin_fact where concat(lstg_format_name,'a')='ABINa'",
+ replacedString);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/examples/test_case_data/sandbox/kylin.properties
----------------------------------------------------------------------
diff --git a/examples/test_case_data/sandbox/kylin.properties b/examples/test_case_data/sandbox/kylin.properties
index 35386de..6a571df 100644
--- a/examples/test_case_data/sandbox/kylin.properties
+++ b/examples/test_case_data/sandbox/kylin.properties
@@ -186,14 +186,14 @@ kylin.engine.spark-conf.spark.yarn.am.extraJavaOptions=-Dhdp.version=current
kylin.engine.spark-conf.spark.executor.extraJavaOptions=-Dhdp.version=current
-### AD-HOC QUERY ###
-#kylin.query.ad-hoc.runner-class-name=org.apache.kylin.query.adhoc.AdHocRunnerJdbcImpl
+### QUERY PUSH DOWN ###
+#kylin.query.pushdown.runner-class-name=org.apache.kylin.query.adhoc.PushDownRunnerJdbcImpl
-#kylin.query.ad-hoc.jdbc.url=jdbc:hive2://sandbox:10000/default
-#kylin.query.ad-hoc.jdbc.driver=org.apache.hive.jdbc.HiveDriver
-#kylin.query.ad-hoc.jdbc.username=hive
-#kylin.query.ad-hoc.jdbc.password=
+#kylin.query.pushdown.jdbc.url=jdbc:hive2://sandbox:10000/default
+#kylin.query.pushdown.jdbc.driver=org.apache.hive.jdbc.HiveDriver
+#kylin.query.pushdown.jdbc.username=hive
+#kylin.query.pushdown.jdbc.password=
-#kylin.query.ad-hoc.jdbc.pool-max-total=8
-#kylin.query.ad-hoc.jdbc.pool-max-idle=8
-#kylin.query.ad-hoc.jdbc.pool-min-idle=0
+#kylin.query.pushdown.jdbc.pool-max-total=8
+#kylin.query.pushdown.jdbc.pool-max-idle=8
+#kylin.query.pushdown.jdbc.pool-min-idle=0
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
index af05237..3634100 100644
--- a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
+++ b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
@@ -51,7 +51,7 @@ import org.apache.kylin.metadata.project.ProjectInstance;
import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
import org.apache.kylin.query.relnode.OLAPContext;
import org.apache.kylin.query.routing.rules.RemoveBlackoutRealizationsRule;
-import org.apache.kylin.rest.util.AdHocUtil;
+import org.apache.kylin.rest.util.PushDownUtil;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseConnection;
@@ -263,7 +263,7 @@ public class KylinTestBase {
} catch (SQLException sqlException) {
List<List<String>> results = Lists.newArrayList();
List<SelectedColumnMeta> columnMetas = Lists.newArrayList();
- AdHocUtil.doAdHocQuery(ProjectInstance.DEFAULT_PROJECT_NAME, sql, results, columnMetas, sqlException);
+ PushDownUtil.doPushDownQuery(ProjectInstance.DEFAULT_PROJECT_NAME, sql, results, columnMetas, sqlException);
return results.size();
} finally {
if (resultSet != null) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/query/src/main/java/org/apache/kylin/query/adhoc/AdHocRunnerJdbcImpl.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/adhoc/AdHocRunnerJdbcImpl.java b/query/src/main/java/org/apache/kylin/query/adhoc/AdHocRunnerJdbcImpl.java
deleted file mode 100644
index 852cebf..0000000
--- a/query/src/main/java/org/apache/kylin/query/adhoc/AdHocRunnerJdbcImpl.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.kylin.query.adhoc;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.commons.pool.impl.GenericObjectPool;
-import org.apache.kylin.common.KylinConfig;
-import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
-import org.apache.kylin.source.adhocquery.IAdHocRunner;
-
-public class AdHocRunnerJdbcImpl implements IAdHocRunner {
-
- private static org.apache.kylin.query.adhoc.JdbcConnectionPool pool = null;
-
- @Override
- public void init(KylinConfig config) {
- if (pool == null) {
- pool = new JdbcConnectionPool();
- JdbcConnectionFactory factory = new JdbcConnectionFactory(config.getJdbcUrl(), config.getJdbcDriverClass(),
- config.getJdbcUsername(), config.getJdbcPassword());
- GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
- poolConfig.maxActive = config.getPoolMaxTotal();
- poolConfig.maxIdle = config.getPoolMaxIdle();
- poolConfig.minIdle = config.getPoolMinIdle();
-
- try {
- pool.createPool(factory, poolConfig);
- } catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
- }
-
- @Override
- public void executeQuery(String query, List<List<String>> results, List<SelectedColumnMeta> columnMetas)
- throws Exception {
- Statement statement = null;
- Connection connection = this.getConnection();
- ResultSet resultSet = null;
-
- try {
- statement = connection.createStatement();
- resultSet = statement.executeQuery(query);
- extractResults(resultSet, results);
- } catch (SQLException sqlException) {
- throw sqlException;
- }
-
- //extract column metadata
- ResultSetMetaData metaData = null;
- int columnCount = 0;
- try {
- metaData = resultSet.getMetaData();
- columnCount = metaData.getColumnCount();
-
- // fill in selected column meta
- for (int i = 1; i <= columnCount; ++i) {
- columnMetas.add(new SelectedColumnMeta(metaData.isAutoIncrement(i), metaData.isCaseSensitive(i), false,
- metaData.isCurrency(i), metaData.isNullable(i), false, metaData.getColumnDisplaySize(i),
- metaData.getColumnLabel(i), metaData.getColumnName(i), null, null, null,
- metaData.getPrecision(i), metaData.getScale(i), metaData.getColumnType(i),
- metaData.getColumnTypeName(i), metaData.isReadOnly(i), false, false));
- }
-
- } catch (SQLException sqlException) {
- throw sqlException;
- }
-
- closeConnection(connection);
- }
-
- private Connection getConnection() {
- return pool.getConnection();
- }
-
- private void closeConnection(Connection connection) {
- pool.returnConnection(connection);
- }
-
- static void extractResults(ResultSet resultSet, List<List<String>> results) throws SQLException {
- List<String> oneRow = new LinkedList<String>();
-
- try {
- while (resultSet.next()) {
- //logger.debug("resultSet value: " + resultSet.getString(1));
- for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {
- oneRow.add((resultSet.getString(i + 1)));
- }
-
- results.add(new LinkedList<String>(oneRow));
- oneRow.clear();
- }
- } catch (SQLException sqlException) {
- throw sqlException;
- }
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/query/src/main/java/org/apache/kylin/query/adhoc/PushDownRunnerJdbcImpl.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/adhoc/PushDownRunnerJdbcImpl.java b/query/src/main/java/org/apache/kylin/query/adhoc/PushDownRunnerJdbcImpl.java
new file mode 100644
index 0000000..8001880
--- /dev/null
+++ b/query/src/main/java/org/apache/kylin/query/adhoc/PushDownRunnerJdbcImpl.java
@@ -0,0 +1,122 @@
+/*
+ * 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.kylin.query.adhoc;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
+import org.apache.kylin.source.adhocquery.IPushDownRunner;
+
+public class PushDownRunnerJdbcImpl implements IPushDownRunner {
+
+ private static org.apache.kylin.query.adhoc.JdbcConnectionPool pool = null;
+
+ @Override
+ public void init(KylinConfig config) {
+ if (pool == null) {
+ pool = new JdbcConnectionPool();
+ JdbcConnectionFactory factory = new JdbcConnectionFactory(config.getJdbcUrl(), config.getJdbcDriverClass(),
+ config.getJdbcUsername(), config.getJdbcPassword());
+ GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
+ poolConfig.maxActive = config.getPoolMaxTotal();
+ poolConfig.maxIdle = config.getPoolMaxIdle();
+ poolConfig.minIdle = config.getPoolMinIdle();
+
+ try {
+ pool.createPool(factory, poolConfig);
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+ }
+
+ @Override
+ public void executeQuery(String query, List<List<String>> results, List<SelectedColumnMeta> columnMetas)
+ throws Exception {
+ Statement statement = null;
+ Connection connection = this.getConnection();
+ ResultSet resultSet = null;
+
+ try {
+ statement = connection.createStatement();
+ resultSet = statement.executeQuery(query);
+ extractResults(resultSet, results);
+ } catch (SQLException sqlException) {
+ throw sqlException;
+ }
+
+ //extract column metadata
+ ResultSetMetaData metaData = null;
+ int columnCount = 0;
+ try {
+ metaData = resultSet.getMetaData();
+ columnCount = metaData.getColumnCount();
+
+ // fill in selected column meta
+ for (int i = 1; i <= columnCount; ++i) {
+ columnMetas.add(new SelectedColumnMeta(metaData.isAutoIncrement(i), metaData.isCaseSensitive(i), false,
+ metaData.isCurrency(i), metaData.isNullable(i), false, metaData.getColumnDisplaySize(i),
+ metaData.getColumnLabel(i), metaData.getColumnName(i), null, null, null,
+ metaData.getPrecision(i), metaData.getScale(i), metaData.getColumnType(i),
+ metaData.getColumnTypeName(i), metaData.isReadOnly(i), false, false));
+ }
+
+ } catch (SQLException sqlException) {
+ throw sqlException;
+ }
+
+ closeConnection(connection);
+ }
+
+ private Connection getConnection() {
+ return pool.getConnection();
+ }
+
+ private void closeConnection(Connection connection) {
+ pool.returnConnection(connection);
+ }
+
+ static void extractResults(ResultSet resultSet, List<List<String>> results) throws SQLException {
+ List<String> oneRow = new LinkedList<String>();
+
+ try {
+ while (resultSet.next()) {
+ //logger.debug("resultSet value: " + resultSet.getString(1));
+ for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {
+ oneRow.add((resultSet.getString(i + 1)));
+ }
+
+ results.add(new LinkedList<String>(oneRow));
+ oneRow.clear();
+ }
+ } catch (SQLException sqlException) {
+ throw sqlException;
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/server-base/src/main/java/org/apache/kylin/rest/response/SQLResponse.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/response/SQLResponse.java b/server-base/src/main/java/org/apache/kylin/rest/response/SQLResponse.java
index d841dee..79a2c05 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/response/SQLResponse.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/response/SQLResponse.java
@@ -61,12 +61,13 @@ public class SQLResponse implements Serializable {
protected boolean storageCacheUsed = false;
- protected boolean queryAdHoc = false;
+ protected boolean queryPushDown = false;
public SQLResponse() {
}
- public SQLResponse(List<SelectedColumnMeta> columnMetas, List<List<String>> results, int affectedRowCount, boolean isException, String exceptionMessage) {
+ public SQLResponse(List<SelectedColumnMeta> columnMetas, List<List<String>> results, int affectedRowCount,
+ boolean isException, String exceptionMessage) {
this.columnMetas = columnMetas;
this.results = results;
this.affectedRowCount = affectedRowCount;
@@ -74,7 +75,8 @@ public class SQLResponse implements Serializable {
this.exceptionMessage = exceptionMessage;
}
- public SQLResponse(List<SelectedColumnMeta> columnMetas, List<List<String>> results, String cube, int affectedRowCount, boolean isException, String exceptionMessage) {
+ public SQLResponse(List<SelectedColumnMeta> columnMetas, List<List<String>> results, String cube,
+ int affectedRowCount, boolean isException, String exceptionMessage) {
this.columnMetas = columnMetas;
this.results = results;
this.cube = cube;
@@ -83,7 +85,8 @@ public class SQLResponse implements Serializable {
this.exceptionMessage = exceptionMessage;
}
- public SQLResponse(List<SelectedColumnMeta> columnMetas, List<List<String>> results, String cube, int affectedRowCount, boolean isException, String exceptionMessage, boolean isPartial, boolean isAdhoc) {
+ public SQLResponse(List<SelectedColumnMeta> columnMetas, List<List<String>> results, String cube,
+ int affectedRowCount, boolean isException, String exceptionMessage, boolean isPartial, boolean isPushDown) {
this.columnMetas = columnMetas;
this.results = results;
this.cube = cube;
@@ -91,7 +94,7 @@ public class SQLResponse implements Serializable {
this.isException = isException;
this.exceptionMessage = exceptionMessage;
this.isPartial = isPartial;
- this.queryAdHoc = isAdhoc;
+ this.queryPushDown = isPushDown;
}
public List<SelectedColumnMeta> getColumnMetas() {
@@ -147,8 +150,8 @@ public class SQLResponse implements Serializable {
return isPartial;
}
- public boolean isAdHoc() {
- return queryAdHoc;
+ public boolean isPushDown() {
+ return queryPushDown;
}
public long getTotalScanCount() {
[08/26] kylin git commit: minor, refine acl
Posted by li...@apache.org.
minor, refine acl
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/c490e6cf
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/c490e6cf
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/c490e6cf
Branch: refs/heads/kylin-2.1.x
Commit: c490e6cf7c01e0e1443fa93fac681300f96680d6
Parents: 8e1a7d5
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 29 16:34:52 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Thu Jun 29 16:36:57 2017 +0800
----------------------------------------------------------------------
.../kylin/rest/controller/CubeController.java | 15 ++-
.../rest/controller2/AccessControllerV2.java | 16 ++-
.../kylin/rest/service/AccessService.java | 26 +++--
.../apache/kylin/rest/service/CubeService.java | 109 +++++++++++++++----
4 files changed, 131 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/c490e6cf/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
index 6916dd8..a370292 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
@@ -352,7 +352,7 @@ public class CubeController extends BasicController {
@ResponseBody
public CubeInstance cloneCube(@PathVariable String cubeName, @RequestBody CubeRequest cubeRequest) {
String newCubeName = cubeRequest.getCubeName();
- String project = cubeRequest.getProject();
+ String projectName = cubeRequest.getProject();
CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
if (cube == null) {
@@ -366,6 +366,11 @@ public class CubeController extends BasicController {
throw new BadRequestException("Invalid Cube name, only letters, numbers and underline supported.");
}
+ ProjectInstance project = cubeService.getProjectManager().getProject(projectName);
+ if (project == null) {
+ throw new BadRequestException("Project " + projectName + " doesn't exist");
+ }
+
CubeDesc cubeDesc = cube.getDescriptor();
CubeDesc newCubeDesc = CubeDesc.getCopyOf(cubeDesc);
@@ -373,7 +378,7 @@ public class CubeController extends BasicController {
CubeInstance newCube;
try {
- newCube = cubeService.createCubeAndDesc(newCubeName, project, newCubeDesc);
+ newCube = cubeService.createCubeAndDesc(project, newCubeDesc);
//reload to avoid shallow clone
cubeService.getCubeDescManager().reloadCubeDescLocal(newCubeName);
@@ -449,7 +454,11 @@ public class CubeController extends BasicController {
try {
desc.setUuid(UUID.randomUUID().toString());
String projectName = (null == cubeRequest.getProject()) ? ProjectInstance.DEFAULT_PROJECT_NAME : cubeRequest.getProject();
- cubeService.createCubeAndDesc(name, projectName, desc);
+ ProjectInstance project = cubeService.getProjectManager().getProject(projectName);
+ if (project == null) {
+ throw new BadRequestException("Project " + projectName + " doesn't exist");
+ }
+ cubeService.createCubeAndDesc(project, desc);
} catch (Exception e) {
logger.error("Failed to deal with the request.", e);
throw new InternalErrorException(e.getLocalizedMessage(), e);
http://git-wip-us.apache.org/repos/asf/kylin/blob/c490e6cf/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
index 255e312..a61e321 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
@@ -58,7 +58,6 @@ public class AccessControllerV2 extends BasicController {
* @return
* @throws IOException
*/
-
@RequestMapping(value = "/{type}/{uuid}", method = { RequestMethod.GET }, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
@@ -70,6 +69,21 @@ public class AccessControllerV2 extends BasicController {
}
/**
+ * List access entry list of a domain object including its parent
+ * @param type
+ * @param uuid
+ * @return
+ */
+ @RequestMapping(value = "all/{type}/{uuid}", method = { RequestMethod.GET }, produces = {
+ "application/vnd.apache.kylin-v2+json" })
+ @ResponseBody
+ public EnvelopeResponse listAccessEntitiesV2(@PathVariable String type, @PathVariable String uuid) {
+ AclEntity ae = accessService.getAclEntity(type, uuid);
+ Acl acl = accessService.getAcl(ae);
+ return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, accessService.generateListAceResponses(acl), "");
+ }
+
+ /**
* Grant a new access on a domain object to a user/role
*
* @param accessRequest
http://git-wip-us.apache.org/repos/asf/kylin/blob/c490e6cf/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
index e5cd793..3a6d723 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
@@ -20,9 +20,7 @@ package org.apache.kylin.rest.service;
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
-import com.google.common.collect.Sets;
import org.apache.kylin.common.persistence.AclEntity;
import org.apache.kylin.common.persistence.RootPersistentEntity;
import org.apache.kylin.rest.constant.Constant;
@@ -300,16 +298,9 @@ public class AccessService {
public List<AccessEntryResponse> generateAceResponses(Acl acl) {
List<AccessEntryResponse> result = new ArrayList<AccessEntryResponse>();
- Set<Sid> sidSet = Sets.newHashSet();
- while (acl != null) {
- for (AccessControlEntry ace : acl.getEntries()) {
- if (!sidSet.contains(ace.getSid())) {
- result.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
- sidSet.add(ace.getSid());
- }
- }
- acl = acl.getParentAcl();
+ for (AccessControlEntry ace : acl.getEntries()) {
+ result.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
}
return result;
@@ -330,4 +321,17 @@ public class AccessService {
throw new ForbiddenException(msg.getREVOKE_ADMIN_PERMISSION());
}
}
+
+ public Object generateListAceResponses(Acl acl) {
+ List<AccessEntryResponse> result = new ArrayList<AccessEntryResponse>();
+
+ while (acl != null) {
+ for (AccessControlEntry ace : acl.getEntries()) {
+ result.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
+ }
+ acl = acl.getParentAcl();
+ }
+
+ return result;
+ }
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/c490e6cf/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java b/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
index a5fc36a..b2e44f6 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
@@ -58,6 +58,7 @@ import org.apache.kylin.rest.request.MetricsRequest;
import org.apache.kylin.rest.response.HBaseResponse;
import org.apache.kylin.rest.response.MetricsResponse;
import org.apache.kylin.rest.security.AclPermission;
+import org.apache.kylin.rest.util.AclUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -96,6 +97,9 @@ public class CubeService extends BasicService {
@Qualifier("modelMgmtService")
private ModelService modelService;
+ @Autowired
+ private AclUtil aclUtil;
+
@PostFilter(Constant.ACCESS_POST_FILTER_READ)
public List<CubeInstance> listAllCubes(final String cubeName, final String projectName, final String modelName, boolean exactMatch) {
List<CubeInstance> cubeInstances = null;
@@ -153,9 +157,11 @@ public class CubeService extends BasicService {
return getCubeManager().updateCube(cubeBuilder);
}
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
- public CubeInstance createCubeAndDesc(String cubeName, String projectName, CubeDesc desc) throws IOException {
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN
+ + " or hasPermission(#project, 'ADMINISTRATION') or hasPermission(#project, 'MANAGEMENT')")
+ public CubeInstance createCubeAndDesc(ProjectInstance project, CubeDesc desc) throws IOException {
Message msg = MsgPicker.getMsg();
+ String cubeName = desc.getName();
if (getCubeManager().getCube(cubeName) != null) {
throw new BadRequestException(String.format(msg.getCUBE_ALREADY_EXIST(), cubeName));
@@ -178,10 +184,9 @@ public class CubeService extends BasicService {
int cuboidCount = CuboidCLI.simulateCuboidGeneration(createdDesc, false);
logger.info("New cube " + cubeName + " has " + cuboidCount + " cuboids");
- createdCube = getCubeManager().createCube(cubeName, projectName, createdDesc, owner);
+ createdCube = getCubeManager().createCube(cubeName, project.getName(), createdDesc, owner);
accessService.init(createdCube, AclPermission.ADMINISTRATION);
- ProjectInstance project = getProjectManager().getProject(projectName);
accessService.inherit(createdCube, project);
return createdCube;
@@ -611,32 +616,69 @@ public class CubeService extends BasicService {
}
}
- public CubeDesc updateCubeToResourceStore(CubeDesc desc, String projectName) throws IOException {
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN
+ + " or hasPermission(#project, 'ADMINISTRATION') or hasPermission(#project, 'MANAGEMENT')")
+ public CubeDesc saveCube(CubeDesc desc, ProjectInstance project) throws IOException {
Message msg = MsgPicker.getMsg();
desc.setDraft(false);
if (desc.getUuid() == null)
desc.updateRandomUuid();
- String cubeName = desc.getName();
try {
- if (desc.getLastModified() == 0) {
- // new
- createCubeAndDesc(cubeName, projectName, desc);
- } else {
- // update
- CubeInstance cube = getCubeManager().getCube(desc.getName());
+ createCubeAndDesc(project, desc);
+ } catch (AccessDeniedException accessDeniedException) {
+ throw new ForbiddenException(msg.getUPDATE_CUBE_NO_RIGHT());
+ }
- if (cube == null) {
- throw new BadRequestException(String.format(msg.getCUBE_NOT_FOUND(), desc.getName()));
- }
+ if (!desc.getError().isEmpty()) {
+ throw new BadRequestException(desc.getErrorMsg());
+ }
- if (cube.getSegments().size() != 0 && !cube.getDescriptor().consistentWith(desc)) {
- throw new BadRequestException(String.format(msg.getINCONSISTENT_CUBE_DESC(), desc.getName()));
- }
+ return desc;
+ }
+
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN
+ + " or hasPermission(#cube, 'ADMINISTRATION') or hasPermission(#cube, 'MANAGEMENT')")
+ public void saveDraft(ProjectInstance project, CubeInstance cube, String uuid, RootPersistentEntity... entities)
+ throws IOException {
+ Draft draft = new Draft();
+ draft.setProject(project.getName());
+ draft.setUuid(uuid);
+ draft.setEntities(entities);
+ getDraftManager().save(draft);
+ }
+
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN
+ + " or hasPermission(#project, 'ADMINISTRATION') or hasPermission(#project, 'MANAGEMENT')")
+ public void saveDraft(ProjectInstance project, String uuid, RootPersistentEntity... entities) throws IOException {
+ Draft draft = new Draft();
+ draft.setProject(project.getName());
+ draft.setUuid(uuid);
+ draft.setEntities(entities);
+ getDraftManager().save(draft);
+ }
+
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN
+ + " or hasPermission(#draft, 'ADMINISTRATION') or hasPermission(#draft, 'MANAGEMENT')")
+ public void deleteDraft(Draft draft) throws IOException {
+ getDraftManager().delete(draft.getUuid());
+ }
- desc = updateCubeAndDesc(cube, desc, projectName, true);
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN
+ + " or hasPermission(#cube, 'ADMINISTRATION') or hasPermission(#cube, 'MANAGEMENT')")
+ public CubeDesc updateCube(CubeInstance cube, CubeDesc desc, ProjectInstance project) throws IOException {
+ Message msg = MsgPicker.getMsg();
+ String projectName = project.getName();
+
+ desc.setDraft(false);
+
+ try {
+ if (cube.getSegments().size() != 0 && !cube.getDescriptor().consistentWith(desc)) {
+ throw new BadRequestException(String.format(msg.getINCONSISTENT_CUBE_DESC(), desc.getName()));
}
+
+ desc = updateCubeAndDesc(cube, desc, projectName, true);
} catch (AccessDeniedException accessDeniedException) {
throw new ForbiddenException(msg.getUPDATE_CUBE_NO_RIGHT());
}
@@ -671,6 +713,33 @@ public class CubeService extends BasicService {
}
}
- return result;
+ List<Draft> filtered = new ArrayList<>();
+
+ // if cube's there, follow cube permission. otherwise follow project permission
+ for (Draft d : result) {
+ CubeDesc desc = (CubeDesc) d.getEntity();
+ CubeInstance cube = getCubeManager().getCube(desc.getName());
+
+ if (cube == null) {
+ try {
+ project = project == null ? d.getProject() : project;
+ if (aclUtil.hasProjectReadPermission(getProjectManager().getProject(project))) {
+ filtered.add(d);
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ } else {
+ try {
+ if (aclUtil.hasCubeReadPermission(cube)) {
+ filtered.add(d);
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }
+
+ return filtered;
}
}
[18/26] kylin git commit: minor,
validate join key should be a dimension
Posted by li...@apache.org.
minor, validate join key should be a dimension
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/6228f886
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/6228f886
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/6228f886
Branch: refs/heads/kylin-2.1.x
Commit: 6228f886ecf697a41fd658b6eb46dde149cd0e2a
Parents: cf1ba95
Author: Cheng Wang <ch...@kyligence.io>
Authored: Fri Jun 30 18:09:18 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 30 18:20:45 2017 +0800
----------------------------------------------------------------------
.../kylin/metadata/model/DataModelDesc.java | 31 ++++++++++++++++++++
.../localmeta/model_desc/ssb.json | 20 ++++++-------
2 files changed, 41 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/6228f886/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
index bc35e2a..abee71b 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
@@ -617,7 +617,38 @@ public class DataModelDesc extends RootPersistentEntity {
+ fkCols[i].getDatatype());
}
}
+
+ if (!isSpecialTestModel()) {
+ for (TblColRef t : fkCols) {
+ if (!isJoinKeyDimension(t.getIdentity())) {
+ throw new IllegalStateException(
+ "Foreigner key: " + t.getIdentity() + " should be a dimension.");
+ }
+ }
+
+ for (TblColRef t : pkCols) {
+ if (!isJoinKeyDimension(t.getIdentity())) {
+ throw new IllegalStateException("Primary key: " + t.getIdentity() + " should be a dimension.");
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isJoinKeyDimension(String key) {
+ for (ModelDimensionDesc d : dimensions) {
+ for (String col : d.getColumns()) {
+ if (key.equals(d.getTable() + '.' + col))
+ return true;
+ }
}
+ return false;
+ }
+
+ private boolean isSpecialTestModel() {
+ if (config.isDevEnv() && (name.startsWith("test_kylin_") || name.startsWith("test_streaming")))
+ return true;
+ return false;
}
private void initJoinsTree() {
http://git-wip-us.apache.org/repos/asf/kylin/blob/6228f886/examples/test_case_data/localmeta/model_desc/ssb.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/model_desc/ssb.json b/examples/test_case_data/localmeta/model_desc/ssb.json
index 52b330f..bbac99d 100644
--- a/examples/test_case_data/localmeta/model_desc/ssb.json
+++ b/examples/test_case_data/localmeta/model_desc/ssb.json
@@ -33,20 +33,20 @@
}
} ],
"dimensions" : [ {
- "table" : "SSB.V_LINEORDER",
- "columns" : [ "LO_DATE" ]
+ "table" : "V_LINEORDER",
+ "columns" : [ "LO_DATE", "LO_PARTKEY", "LO_CUSTKEY", "LO_ORDERDATE", "LO_SUPPKEY" ]
}, {
- "table" : "SSB.PART",
- "columns" : [ "P_MFGR", "P_CATEGORY", "P_BRAND" ]
+ "table" : "PART",
+ "columns" : [ "P_MFGR", "P_CATEGORY", "P_BRAND", "P_PARTKEY" ]
}, {
- "table" : "SSB.CUSTOMER",
- "columns" : [ "C_CITY", "C_NATION", "C_REGION" ]
+ "table" : "CUSTOMER",
+ "columns" : [ "C_CITY", "C_NATION", "C_REGION", "C_CUSTKEY" ]
}, {
- "table" : "SSB.SUPPLIER",
- "columns" : [ "S_CITY", "S_NATION", "S_REGION" ]
+ "table" : "SUPPLIER",
+ "columns" : [ "S_CITY", "S_NATION", "S_REGION", "S_SUPPKEY" ]
}, {
- "table" : "SSB.DATES",
- "columns" : [ "D_YEAR", "D_YEARMONTHNUM", "D_YEARMONTH", "D_WEEKNUMINYEAR" ]
+ "table" : "DATES",
+ "columns" : [ "D_YEAR", "D_YEARMONTHNUM", "D_YEARMONTH", "D_WEEKNUMINYEAR", "D_DATEKEY" ]
} ],
"metrics" : [ "LO_REVENUE", "LO_SUPPLYCOST", "V_REVENUE" ],
"last_modified" : 1457444314662,
[11/26] kylin git commit: minor, remove unused API in QueryUtil
Posted by li...@apache.org.
minor, remove unused API in QueryUtil
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/40054dd4
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/40054dd4
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/40054dd4
Branch: refs/heads/kylin-2.1.x
Commit: 40054dd4b263a44bfacf809d614fb9a9d5cce77e
Parents: 052d609
Author: lidongsjtu <li...@apache.org>
Authored: Thu Jun 29 21:29:43 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 29 21:33:04 2017 +0800
----------------------------------------------------------------------
query/src/main/java/org/apache/kylin/query/util/QueryUtil.java | 5 -----
1 file changed, 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/40054dd4/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java b/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
index 7794f94..eff9f6d 100644
--- a/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
+++ b/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
@@ -41,11 +41,6 @@ public class QueryUtil {
String transform(String sql, String project);
}
- // for mockup test
- public static String massageSql(String sql) {
- return massageSql(sql, null, 0, 0);
- }
-
public static String massageSql(String sql, String project, int limit, int offset) {
sql = sql.trim();
sql = sql.replace("\r", " ").replace("\n", System.getProperty("line.separator"));
[15/26] kylin git commit: minor, make calcite work with unicode
Posted by li...@apache.org.
minor, make calcite work with unicode
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/f52eb0c5
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/f52eb0c5
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/f52eb0c5
Branch: refs/heads/kylin-2.1.x
Commit: f52eb0c5c667b655d9a20f6226af2a3f5cbe0f4e
Parents: 2546e00
Author: Li Yang <li...@apache.org>
Authored: Fri Jun 30 13:42:21 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 30 13:46:14 2017 +0800
----------------------------------------------------------------------
.../org/apache/kylin/common/KylinConfig.java | 21 ++++++++++++++++++++
.../apache/kylin/query/ITCombinationTest.java | 3 +--
.../org/apache/kylin/query/KylinTestBase.java | 4 ++--
.../kylin/query/schema/OLAPSchemaFactory.java | 19 ------------------
4 files changed, 24 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/f52eb0c5/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
----------------------------------------------------------------------
diff --git a/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java b/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
index 1298807..cc08056 100644
--- a/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
+++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
@@ -28,6 +28,7 @@ import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.URL;
+import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Map;
@@ -58,6 +59,26 @@ public class KylinConfig extends KylinConfigBase {
// thread-local instances, will override SYS_ENV_INSTANCE
private static transient ThreadLocal<KylinConfig> THREAD_ENV_INSTANCE = new ThreadLocal<>();
+
+ static {
+ /*
+ * Make Calcite to work with Unicode.
+ *
+ * Sets default char set for string literals in SQL and row types of
+ * RelNode. This is more a label used to compare row type equality. For
+ * both SQL string and row record, they are passed to Calcite in String
+ * object and does not require additional codec.
+ *
+ * Ref SaffronProperties.defaultCharset
+ * Ref SqlUtil.translateCharacterSetName()
+ * Ref NlsString constructor()
+ */
+ // copied from org.apache.calcite.util.ConversionUtil.NATIVE_UTF16_CHARSET_NAME
+ String NATIVE_UTF16_CHARSET_NAME = (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) ? "UTF-16BE" : "UTF-16LE";
+ System.setProperty("saffron.default.charset", NATIVE_UTF16_CHARSET_NAME);
+ System.setProperty("saffron.default.nationalcharset", NATIVE_UTF16_CHARSET_NAME);
+ System.setProperty("saffron.default.collation.name", NATIVE_UTF16_CHARSET_NAME + "$en_US");
+ }
public static KylinConfig getInstanceFromEnv() {
synchronized (KylinConfig.class) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/f52eb0c5/kylin-it/src/test/java/org/apache/kylin/query/ITCombinationTest.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/query/ITCombinationTest.java b/kylin-it/src/test/java/org/apache/kylin/query/ITCombinationTest.java
index 0bed5ed..5051db1 100644
--- a/kylin-it/src/test/java/org/apache/kylin/query/ITCombinationTest.java
+++ b/kylin-it/src/test/java/org/apache/kylin/query/ITCombinationTest.java
@@ -18,7 +18,6 @@
package org.apache.kylin.query;
-import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
@@ -43,7 +42,7 @@ public class ITCombinationTest extends ITKylinQueryTest {
private static final Logger logger = LoggerFactory.getLogger(ITCombinationTest.class);
@BeforeClass
- public static void setUp() throws SQLException {
+ public static void setUp() {
Map<RealizationType, Integer> priorities = Maps.newHashMap();
priorities.put(RealizationType.HYBRID, 0);
priorities.put(RealizationType.CUBE, 0);
http://git-wip-us.apache.org/repos/asf/kylin/blob/f52eb0c5/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
index a05d0c3..af05237 100644
--- a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
+++ b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
@@ -21,9 +21,9 @@ package org.apache.kylin.query;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
@@ -166,7 +166,7 @@ public class KylinTestBase {
}
public static String getTextFromFile(File file) throws IOException {
- BufferedReader reader = new BufferedReader(new FileReader(file));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
http://git-wip-us.apache.org/repos/asf/kylin/blob/f52eb0c5/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java b/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
index bfe49cf..c098b23 100644
--- a/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
+++ b/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
@@ -31,7 +31,6 @@ import java.util.Map.Entry;
import org.apache.calcite.schema.Schema;
import org.apache.calcite.schema.SchemaFactory;
import org.apache.calcite.schema.SchemaPlus;
-import org.apache.calcite.util.ConversionUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.kylin.common.KylinConfig;
@@ -50,24 +49,6 @@ import com.google.common.collect.Maps;
public class OLAPSchemaFactory implements SchemaFactory {
public static final Logger logger = LoggerFactory.getLogger(OLAPSchemaFactory.class);
- static {
- /*
- * Tricks Optiq to work with Unicode.
- *
- * Sets default char set for string literals in SQL and row types of
- * RelNode. This is more a label used to compare row type equality. For
- * both SQL string and row record, they are passed to Optiq in String
- * object and does not require additional codec.
- *
- * Ref SaffronProperties.defaultCharset
- * Ref SqlUtil.translateCharacterSetName()
- * Ref NlsString constructor()
- */
- System.setProperty("saffron.default.charset", ConversionUtil.NATIVE_UTF16_CHARSET_NAME);
- System.setProperty("saffron.default.nationalcharset", ConversionUtil.NATIVE_UTF16_CHARSET_NAME);
- System.setProperty("saffron.default.collation.name", ConversionUtil.NATIVE_UTF16_CHARSET_NAME + "$en_US");
- }
-
private final static String SCHEMA_PROJECT = "project";
@Override
[10/26] kylin git commit: minor, fix ACL NPE
Posted by li...@apache.org.
minor, fix ACL NPE
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/052d6096
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/052d6096
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/052d6096
Branch: refs/heads/kylin-2.1.x
Commit: 052d6096779d5826ba24517b0b4cc9a45b78bf4a
Parents: 8ca0d32
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 29 17:23:13 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Thu Jun 29 18:24:43 2017 +0800
----------------------------------------------------------------------
.../main/java/org/apache/kylin/rest/service/AccessService.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/052d6096/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
index affa508..ae7ac6e 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
@@ -19,6 +19,7 @@
package org.apache.kylin.rest.service;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.apache.kylin.common.persistence.AclEntity;
@@ -297,8 +298,11 @@ public class AccessService {
}
public List<AccessEntryResponse> generateAceResponses(Acl acl) {
- List<AccessEntryResponse> result = new ArrayList<AccessEntryResponse>();
+ if (null == acl) {
+ return Collections.emptyList();
+ }
+ List<AccessEntryResponse> result = new ArrayList<AccessEntryResponse>();
for (AccessControlEntry ace : acl.getEntries()) {
result.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
}
[22/26] kylin git commit: minor, refine acl
Posted by li...@apache.org.
minor, refine acl
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/d91f5229
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/d91f5229
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/d91f5229
Branch: refs/heads/kylin-2.1.x
Commit: d91f522904424f59d817bbcde10c47cc68f04d9d
Parents: 3ae8ca7
Author: Roger Shi <ro...@hotmail.com>
Authored: Fri Jun 30 20:52:03 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 30 20:57:18 2017 +0800
----------------------------------------------------------------------
.../hbase/ITAclTableMigrationToolTest.java | 10 ++--
.../rest/controller2/ProjectControllerV2.java | 4 ++
.../org/apache/kylin/rest/msg/CnMessage.java | 2 +-
.../java/org/apache/kylin/rest/msg/Message.java | 2 +-
.../apache/kylin/rest/security/ManagedUser.java | 54 +++++++++++++++++---
.../rest/service/AclTableMigrationTool.java | 2 +-
.../kylin/rest/service/ServiceTestBase.java | 10 ++--
tool-assembly/pom.xml | 1 +
tool/pom.xml | 12 +++++
9 files changed, 79 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITAclTableMigrationToolTest.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITAclTableMigrationToolTest.java b/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITAclTableMigrationToolTest.java
index 2cb671e..05f437d 100644
--- a/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITAclTableMigrationToolTest.java
+++ b/kylin-it/src/test/java/org/apache/kylin/storage/hbase/ITAclTableMigrationToolTest.java
@@ -44,7 +44,6 @@ import org.apache.kylin.common.util.Pair;
import org.apache.kylin.rest.security.AclConstant;
import org.apache.kylin.rest.service.AclService;
import org.apache.kylin.rest.service.AclTableMigrationTool;
-import org.apache.kylin.rest.service.UserGrantedAuthority;
import org.apache.kylin.rest.service.UserService;
import org.apache.kylin.rest.util.Serializer;
import org.junit.After;
@@ -53,6 +52,7 @@ import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -70,7 +70,7 @@ public class ITAclTableMigrationToolTest extends HBaseMetadataTestCase {
private TableName userTable = TableName.valueOf(STORE_WITH_OLD_TABLE + AclConstant.USER_TABLE_NAME);
- private Serializer<UserGrantedAuthority[]> ugaSerializer = new Serializer<UserGrantedAuthority[]>(UserGrantedAuthority[].class);
+ private Serializer<SimpleGrantedAuthority[]> ugaSerializer = new Serializer<>(SimpleGrantedAuthority[].class);
private AclTableMigrationTool aclTableMigrationJob;
@@ -192,13 +192,13 @@ public class ITAclTableMigrationToolTest extends HBaseMetadataTestCase {
if (authorities == null)
authorities = Collections.emptyList();
- UserGrantedAuthority[] serializing = new UserGrantedAuthority[authorities.size() + 1];
+ SimpleGrantedAuthority[] serializing = new SimpleGrantedAuthority[authorities.size() + 1];
// password is stored as the [0] authority
- serializing[0] = new UserGrantedAuthority(AclConstant.PWD_PREFIX + "password");
+ serializing[0] = new SimpleGrantedAuthority(AclConstant.PWD_PREFIX + "password");
int i = 1;
for (GrantedAuthority a : authorities) {
- serializing[i++] = new UserGrantedAuthority(a.getAuthority());
+ serializing[i++] = new SimpleGrantedAuthority(a.getAuthority());
}
byte[] value = ugaSerializer.serialize(serializing);
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
index a25e5b1..d6ac8f2 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
@@ -142,6 +142,10 @@ public class ProjectControllerV2 extends BasicController {
if (projectDesc.getName().equals(currentProject.getName())) {
updatedProj = projectService.updateProject(projectDesc, currentProject);
} else {
+ if (!isProjectEmpty(formerProjectName)) {
+ throw new BadRequestException(msg.getDELETE_PROJECT_NOT_EMPTY());
+ }
+ // disable project rename
updatedProj = projectService.renameProject(projectDesc, currentProject);
}
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, updatedProj, "");
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java b/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
index a828aa0..e086b68 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
@@ -246,7 +246,7 @@ public class CnMessage extends Message {
}
public String getDELETE_PROJECT_NOT_EMPTY() {
- return "不能删除该项目,如需要删除请先清空其中的Cube和Model";
+ return "不能修改该项目,如需要修改请先清空其中的Cube和Model";
}
public String getRENAME_PROJECT_NOT_EMPTY() {
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java b/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
index 45c1a65..f48a217 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
@@ -246,7 +246,7 @@ public class Message {
}
public String getDELETE_PROJECT_NOT_EMPTY() {
- return "Cannot delete non-empty project";
+ return "Cannot modify non-empty project";
}
// Table
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
index 280339e..69326a7 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
@@ -18,6 +18,7 @@
package org.apache.kylin.rest.security;
+import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -25,10 +26,20 @@ import java.util.List;
import org.apache.kylin.common.persistence.RootPersistentEntity;
import org.apache.kylin.rest.service.UserGrantedAuthority;
import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.Lists;
@SuppressWarnings("serial")
@@ -40,7 +51,9 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
@JsonProperty
private String password;
@JsonProperty
- private List<UserGrantedAuthority> authorities = Lists.newArrayList();
+ @JsonSerialize(using = SimpleGrantedAuthoritySerializer.class)
+ @JsonDeserialize(using = SimpleGrantedAuthorityDeserializer.class)
+ private List<SimpleGrantedAuthority> authorities = Lists.newArrayList();
@JsonProperty
private boolean disabled = false;
@JsonProperty
@@ -60,7 +73,7 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
}
public ManagedUser(@JsonProperty String username, @JsonProperty String password,
- @JsonProperty List<UserGrantedAuthority> authorities, @JsonProperty boolean disabled,
+ @JsonProperty List<SimpleGrantedAuthority> authorities, @JsonProperty boolean disabled,
@JsonProperty boolean defaultPassword, @JsonProperty boolean locked, @JsonProperty long lockedTime,
@JsonProperty int wrongTime) {
this.username = username;
@@ -82,7 +95,7 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
this.authorities = Lists.newArrayList();
for (String a : authoritiesStr) {
- authorities.add(new UserGrantedAuthority(a));
+ authorities.add(new SimpleGrantedAuthority(a));
}
caterLegacy();
@@ -116,7 +129,7 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
}
private void caterLegacy() {
- Iterator<UserGrantedAuthority> iterator = authorities.iterator();
+ Iterator<SimpleGrantedAuthority> iterator = authorities.iterator();
while (iterator.hasNext()) {
if (DISABLED_ROLE.equals(iterator.next().getAuthority())) {
iterator.remove();
@@ -125,14 +138,14 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
}
}
- public List<UserGrantedAuthority> getAuthorities() {
+ public List<SimpleGrantedAuthority> getAuthorities() {
return this.authorities;
}
public void setGrantedAuthorities(Collection<? extends GrantedAuthority> grantedAuthorities) {
this.authorities = Lists.newArrayList();
for (GrantedAuthority grantedAuthority : grantedAuthorities) {
- this.authorities.add(new UserGrantedAuthority(grantedAuthority.getAuthority()));
+ this.authorities.add(new SimpleGrantedAuthority(grantedAuthority.getAuthority()));
}
}
@@ -228,4 +241,33 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
public String toString() {
return "ManagedUser [username=" + username + ", authorities=" + authorities + "]";
}
+
+ private static class SimpleGrantedAuthoritySerializer extends JsonSerializer<List<SimpleGrantedAuthority>> {
+
+ @Override
+ public void serialize(List<SimpleGrantedAuthority> value, JsonGenerator gen, SerializerProvider serializers)
+ throws IOException, JsonProcessingException {
+ List<UserGrantedAuthority> ugaList = Lists.newArrayList();
+ for (SimpleGrantedAuthority sga : value) {
+ ugaList.add(new UserGrantedAuthority(sga.getAuthority()));
+ }
+
+ gen.writeObject(ugaList);
+ }
+ }
+
+ private static class SimpleGrantedAuthorityDeserializer extends JsonDeserializer<List<SimpleGrantedAuthority>> {
+
+ @Override
+ public List<SimpleGrantedAuthority> deserialize(JsonParser p, DeserializationContext ctxt)
+ throws IOException, JsonProcessingException {
+ UserGrantedAuthority[] ugaArray = p.readValueAs(UserGrantedAuthority[].class);
+ List<SimpleGrantedAuthority> sgaList = Lists.newArrayList();
+ for (UserGrantedAuthority uga : ugaArray) {
+ sgaList.add(new SimpleGrantedAuthority(uga.getAuthority()));
+ }
+
+ return sgaList;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
index 64bac23..029efdc 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
@@ -193,7 +193,7 @@ public class AclTableMigrationTool {
}
private DomainObjectInfo getDomainObjectInfoFromRs(Result result) {
- String type = String.valueOf(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
+ String type = new String(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_TYPE_COLUMN)));
String id = new String(result.getRow());
DomainObjectInfo newInfo = new DomainObjectInfo();
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java b/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
index 1d60a53..e2f5258 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
@@ -35,6 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
@@ -72,18 +73,19 @@ public class ServiceTestBase extends LocalFileMetadataTestCase {
if (!userService.userExists("ADMIN")) {
userService.createUser(new ManagedUser("ADMIN", "KYLIN", false, Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ADMIN), new UserGrantedAuthority(Constant.ROLE_ANALYST),
- new UserGrantedAuthority(Constant.ROLE_MODELER))));
+ new SimpleGrantedAuthority(Constant.ROLE_ADMIN), new SimpleGrantedAuthority(Constant.ROLE_ANALYST),
+ new SimpleGrantedAuthority(Constant.ROLE_MODELER))));
}
if (!userService.userExists("MODELER")) {
userService.createUser(new ManagedUser("MODELER", "MODELER", false, Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ANALYST), new UserGrantedAuthority(Constant.ROLE_MODELER))));
+ new SimpleGrantedAuthority(Constant.ROLE_ANALYST),
+ new SimpleGrantedAuthority(Constant.ROLE_MODELER))));
}
if (!userService.userExists("ANALYST")) {
userService.createUser(new ManagedUser("ANALYST", "ANALYST", false, Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ANALYST))));
+ new SimpleGrantedAuthority(Constant.ROLE_ANALYST))));
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/tool-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/tool-assembly/pom.xml b/tool-assembly/pom.xml
index 0595bdd..df0725b 100644
--- a/tool-assembly/pom.xml
+++ b/tool-assembly/pom.xml
@@ -104,6 +104,7 @@
<include>org.apache.kylin:*</include>
<include>org.springframework.security:spring-security-core</include>
<include>org.springframework.security:spring-security-acl</include>
+ <include>org.springframework:spring-core</include>
</includes>
</artifactSet>
<relocations>
http://git-wip-us.apache.org/repos/asf/kylin/blob/d91f5229/tool/pom.xml
----------------------------------------------------------------------
diff --git a/tool/pom.xml b/tool/pom.xml
index cced5d2..06a7e5a 100644
--- a/tool/pom.xml
+++ b/tool/pom.xml
@@ -32,6 +32,10 @@
<version>2.1.0-SNAPSHOT</version>
</parent>
+ <properties>
+ <spring.framework.version>4.2.8.RELEASE</spring.framework.version>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.apache.kylin</groupId>
@@ -72,6 +76,14 @@
<scope>provided</scope>
</dependency>
+ <!--Spring-->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>${spring.framework.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
<!-- Env & Test -->
<dependency>
<groupId>org.apache.kylin</groupId>
[17/26] kylin git commit: minor, fix computed column and adhoc issues
Posted by li...@apache.org.
minor, fix computed column and adhoc issues
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/cf1ba956
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/cf1ba956
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/cf1ba956
Branch: refs/heads/kylin-2.1.x
Commit: cf1ba9566c2b8ae8aa0f69dc8c27293bee156ab5
Parents: 5fb4f35
Author: Hongbin Ma <ma...@apache.org>
Authored: Fri Jun 30 15:50:09 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 30 16:00:37 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/metadata/MetadataManager.java | 32 +-------
.../kylin/metadata/model/DataModelDesc.java | 80 +++++++++-----------
.../metadata/model/ModelDimensionDesc.java | 12 ++-
.../metadata/model/tool/CalciteParser.java | 9 ++-
.../kylin/model/tool/CalciteParserTest.java | 26 +++++--
.../query/util/ConvertToComputedColumn.java | 36 +++------
.../apache/kylin/rest/service/AclService.java | 4 +-
.../apache/kylin/rest/service/ModelService.java | 2 +-
.../org/apache/kylin/rest/util/AdHocUtil.java | 58 +++++---------
.../apache/kylin/rest/util/AdHocUtilTest.java | 23 +++---
.../kylin/rest/service/ModelServiceTest.java | 4 +-
11 files changed, 116 insertions(+), 170 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java b/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
index 96ae294..6c4faa3 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
@@ -25,7 +25,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -40,7 +39,6 @@ import org.apache.kylin.metadata.cachesync.Broadcaster;
import org.apache.kylin.metadata.cachesync.Broadcaster.Event;
import org.apache.kylin.metadata.cachesync.CaseInsensitiveStringCache;
import org.apache.kylin.metadata.model.ColumnDesc;
-import org.apache.kylin.metadata.model.ComputedColumnDesc;
import org.apache.kylin.metadata.model.DataModelDesc;
import org.apache.kylin.metadata.model.ExternalFilterDesc;
import org.apache.kylin.metadata.model.TableDesc;
@@ -120,26 +118,6 @@ public class MetadataManager {
// name => External Filter Desc
private CaseInsensitiveStringCache<ExternalFilterDesc> extFilterMap;
- public static class CCInfo {
- private ComputedColumnDesc computedColumnDesc;
- private Set<DataModelDesc> dataModelDescs;
-
- public CCInfo(ComputedColumnDesc computedColumnDesc, Set<DataModelDesc> dataModelDescs) {
- this.computedColumnDesc = computedColumnDesc;
- this.dataModelDescs = dataModelDescs;
- }
-
- public ComputedColumnDesc getComputedColumnDesc() {
- return computedColumnDesc;
- }
-
- public Set<DataModelDesc> getDataModelDescs() {
- return dataModelDescs;
- }
- }
-
- private Map<String, CCInfo> ccInfoMap = Maps.newHashMap();// this is to check any two models won't conflict computed columns
-
private MetadataManager(KylinConfig config) throws IOException {
init(config);
}
@@ -181,9 +159,6 @@ public class MetadataManager {
return Collections.unmodifiableMap(srcTableMap.getMap());
}
- public Map<String, CCInfo> getCcInfoMap() {
- return ccInfoMap;
- }
public Map<String, TableExtDesc> listAllTableExdMap() {
return srcTableExdMap.getMap();
@@ -373,7 +348,6 @@ public class MetadataManager {
@Override
public void onProjectSchemaChange(Broadcaster broadcaster, String project) throws IOException {
- ccInfoMap.clear();
for (String model : ProjectManager.getInstance(config).getProject(project).getModels()) {
reloadDataModelDescAt(DataModelDesc.concatResourcePath(model));
}
@@ -546,7 +520,7 @@ public class MetadataManager {
return new ArrayList<>(dataModelDescMap.values());
}
- public List<DataModelDesc> getModels(String projectName) throws IOException {
+ public List<DataModelDesc> getModels(String projectName) {
ProjectInstance projectInstance = ProjectManager.getInstance(config).getProject(projectName);
ArrayList<DataModelDesc> ret = new ArrayList<>();
@@ -618,7 +592,7 @@ public class MetadataManager {
DataModelDesc dataModelDesc = store.getResource(path, DataModelDesc.class, MODELDESC_SERIALIZER);
if (!dataModelDesc.isDraft())
- dataModelDesc.init(config, this.getAllTablesMap(), this.ccInfoMap);
+ dataModelDesc.init(config, this.getAllTablesMap(), listDataModels());
dataModelDescMap.putLocal(dataModelDesc.getName(), dataModelDesc);
return dataModelDesc;
@@ -669,7 +643,7 @@ public class MetadataManager {
private DataModelDesc saveDataModelDesc(DataModelDesc dataModelDesc) throws IOException {
if (!dataModelDesc.isDraft())
- dataModelDesc.init(config, this.getAllTablesMap(), this.ccInfoMap);
+ dataModelDesc.init(config, this.getAllTablesMap(), listDataModels());
String path = dataModelDesc.getResourcePath();
getStore().putResource(path, dataModelDesc, MODELDESC_SERIALIZER);
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
index 341f36e..bc35e2a 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
@@ -18,8 +18,6 @@
package org.apache.kylin.metadata.model;
-import static org.apache.kylin.metadata.MetadataManager.CCInfo;
-
import java.io.Serializable;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -38,6 +36,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.persistence.ResourceStore;
import org.apache.kylin.common.persistence.RootPersistentEntity;
+import org.apache.kylin.common.util.Pair;
import org.apache.kylin.common.util.StringUtil;
import org.apache.kylin.metadata.MetadataConstants;
import org.apache.kylin.metadata.model.JoinsTree.Chain;
@@ -49,6 +48,7 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
@@ -234,6 +234,7 @@ public class DataModelDesc extends RootPersistentEntity {
return factTableRefs.contains(t);
}
+ //TODO: different from isFactTable(TableRef t)
public boolean isFactTable(String fullTableName) {
for (TableRef t : factTableRefs) {
if (t.getTableIdentity().equals(fullTableName))
@@ -332,7 +333,7 @@ public class DataModelDesc extends RootPersistentEntity {
throw new IllegalArgumentException("Table not found by " + tableIdentity + " in model " + name);
}
- public void init(KylinConfig config, Map<String, TableDesc> originalTables, Map<String, CCInfo> ccInfoMap) {
+ public void init(KylinConfig config, Map<String, TableDesc> originalTables, List<DataModelDesc> dataModelDescs) {
//tweak the tables according to Computed Columns defined in model
Map<String, TableDesc> tables = Maps.newHashMap();
for (Map.Entry<String, TableDesc> entry : originalTables.entrySet()) {
@@ -351,12 +352,12 @@ public class DataModelDesc extends RootPersistentEntity {
initJoinsTree();
initDimensionsAndMetrics();
initPartitionDesc();
- initComputedColumns(ccInfoMap);
+ initComputedColumns(dataModelDescs);
initFilterCondition();
boolean reinit = validate();
if (reinit) { // model slightly changed by validate() and must init() again
- init(config, tables, ccInfoMap);
+ init(config, tables, dataModelDescs);
}
}
@@ -471,38 +472,43 @@ public class DataModelDesc extends RootPersistentEntity {
this.partitionDesc.init(this);
}
- private void initComputedColumns(Map<String, CCInfo> ccInfoMap) {
- if (ccInfoMap == null) {
- logger.error("cc info map is null");
+ private void initComputedColumns(List<DataModelDesc> allDataModelDescs) {
+ Preconditions.checkNotNull(allDataModelDescs);
+
+ List<Pair<ComputedColumnDesc, DataModelDesc>> existingCCs = Lists.newArrayList();
+
+ for (DataModelDesc dataModelDesc : allDataModelDescs) {
+ if (!StringUtils.equals(dataModelDesc.getName(), this.getName())) {
+ for (ComputedColumnDesc cc : dataModelDesc.getComputedColumnDescs()) {
+ existingCCs.add(Pair.newPair(cc, dataModelDesc));
+ }
+ }
}
- Set<String> ccSet = Sets.newHashSet();//make sure cc name does not duplicate within this model
+ for (ComputedColumnDesc newCC : this.computedColumnDescs) {
- for (ComputedColumnDesc thisCCDesc : this.computedColumnDescs) {
- thisCCDesc.init();
- String thisCCName = thisCCDesc.getFullName();
+ newCC.init();
+ final String newCCName = newCC.getFullName();
+ final String newCCColumnName = newCC.getColumnName();
- if (ccSet.contains(thisCCName)) {
- throw new IllegalArgumentException(String.format(
- "More than one computed column named %s exist in model %s", thisCCName, this.getName()));
- } else {
- ccSet.add(thisCCName);
- }
+ for (Pair<ComputedColumnDesc, DataModelDesc> pair : existingCCs) {
+ DataModelDesc dataModelDesc = pair.getSecond();
+ ComputedColumnDesc cc = pair.getFirst();
- CCInfo other = ccInfoMap.get(thisCCName);
+ if (StringUtils.equals(cc.getFullName(), newCCName) && !(cc.equals(newCC))) {
+ throw new IllegalArgumentException(
+ String.format("Computed column named %s is defined differently in model %s", newCCName,
+ dataModelDesc.getName()));
+ }
- if (other == null) {
- checkSameCCDefinition(ccInfoMap, thisCCDesc, thisCCName);
- ccInfoMap.put(thisCCName, new CCInfo(thisCCDesc, Sets.<DataModelDesc> newHashSet(this)));
- } else if (other.getDataModelDescs().size() == 1 && other.getDataModelDescs().contains(this)) {
- ccInfoMap.put(thisCCName, new CCInfo(thisCCDesc, Sets.<DataModelDesc> newHashSet(this)));
- } else if (other.getComputedColumnDesc().equals(thisCCDesc)) {
- other.getDataModelDescs().add(this);
- } else {
- throw new IllegalStateException(String.format(
- "Computed column named %s is already defined in other models: %s. Please change another name, or try to keep consistent definition", //
- thisCCName, other.getDataModelDescs()));
+ if (isTwoCCDefinitionEquals(cc.getExpression(), newCC.getExpression())
+ && !StringUtils.equals(cc.getColumnName(), newCCColumnName)) {
+ throw new IllegalArgumentException(String.format(
+ "Duplicate expression of %s with computed column %s in model %s, keep same computed column name could suppress this",
+ newCCColumnName, cc.getColumnName(), dataModelDesc.getName()));
+ }
}
+ existingCCs.add(Pair.newPair(newCC, this));
}
}
@@ -548,20 +554,6 @@ public class DataModelDesc extends RootPersistentEntity {
}
}
- private void checkSameCCDefinition(Map<String, CCInfo> ccInfoMap, ComputedColumnDesc thisCCDesc,
- String thisCCName) {
- //check whether two computer columns's definition is the same.
- for (CCInfo sysCCInfo : ccInfoMap.values()) {
- String definition0 = thisCCDesc.getExpression();
- String definition1 = sysCCInfo.getComputedColumnDesc().getExpression();
- if (isTwoCCDefinitionEquals(definition0, definition1)) {
- throw new IllegalStateException(String.format(
- "Computed column %s's definition: %s is already defined in other models: %s. Please change another definition, or try to keep consistent definition",
- thisCCName, definition0, sysCCInfo.getDataModelDescs()));
- }
- }
- }
-
private boolean isTwoCCDefinitionEquals(String definition0, String definition1) {
definition0 = definition0.replaceAll("\\s*", "");
definition1 = definition1.replaceAll("\\s*", "");
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/core-metadata/src/main/java/org/apache/kylin/metadata/model/ModelDimensionDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/ModelDimensionDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/ModelDimensionDesc.java
index c0ddbad..283c39c 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/ModelDimensionDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/ModelDimensionDesc.java
@@ -31,7 +31,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class ModelDimensionDesc implements Serializable {
private static final long serialVersionUID = 1L;
-
+
@JsonProperty("table")
private String table;
@JsonProperty("columns")
@@ -58,12 +58,18 @@ public class ModelDimensionDesc implements Serializable {
if (columns != null) {
StringUtil.toUpperCaseArray(columns, columns);
}
-
+
if (model != null) {
table = model.findTable(table).getAlias();
if (columns != null) {
for (int i = 0; i < columns.length; i++) {
- columns[i] = model.findColumn(table, columns[i]).getName();
+ TblColRef column = model.findColumn(table, columns[i]);
+
+ if (column.getColumnDesc().isComputedColumnn() && !model.isFactTable(column.getTableRef())) {
+ throw new RuntimeException("Computed Column on lookup table is not allowed");
+ }
+
+ columns[i] = column.getName();
}
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/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 47a90bf..9b80969 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
@@ -22,7 +22,9 @@ import java.util.Collections;
import java.util.Comparator;
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;
@@ -37,7 +39,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 {
public static SqlNode parse(String sql) throws SqlParseException {
@@ -151,19 +153,20 @@ public class CalciteParser {
String sql = prefix + expr + suffix;
SqlNode sqlNode = getOnlySelectNode(sql);
- final List<SqlIdentifier> sqlIdentifiers = Lists.newArrayList();
+ final Set<SqlIdentifier> s = Sets.newHashSet();
SqlVisitor sqlVisitor = new SqlBasicVisitor() {
@Override
public Object visit(SqlIdentifier id) {
if (id.names.size() > 1) {
throw new IllegalArgumentException("SqlIdentifier " + id + " contains DB/Table name");
}
- sqlIdentifiers.add(id);
+ s.add(id);
return null;
}
};
sqlNode.accept(sqlVisitor);
+ List<SqlIdentifier> sqlIdentifiers = Lists.newArrayList(s);
Collections.sort(sqlIdentifiers, new Comparator<SqlIdentifier>() {
@Override
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/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 acf7b5a..81c1c97 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
@@ -18,12 +18,13 @@
package org.apache.kylin.model.tool;
+import static org.junit.Assert.assertEquals;
+
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.kylin.metadata.model.tool.CalciteParser;
-import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -38,13 +39,13 @@ public class CalciteParserTest {
@Test
public void testNoTableNameExists() throws SqlParseException {
String expr1 = "a + b";
- Assert.assertEquals("x.a + x.b", CalciteParser.insertAliasInExpr(expr1, "x"));
+ assertEquals("x.a + x.b", CalciteParser.insertAliasInExpr(expr1, "x"));
String expr2 = "a + year(b)";
- Assert.assertEquals("x.a + year(x.b)", CalciteParser.insertAliasInExpr(expr2, "x"));
+ assertEquals("x.a + year(x.b)", CalciteParser.insertAliasInExpr(expr2, "x"));
String expr3 = "a + hiveudf(b)";
- Assert.assertEquals("x.a + hiveudf(x.b)", CalciteParser.insertAliasInExpr(expr3, "x"));
+ assertEquals("x.a + hiveudf(x.b)", CalciteParser.insertAliasInExpr(expr3, "x"));
}
@Test
@@ -75,6 +76,17 @@ public class CalciteParserTest {
}
@Test
+ public void testCasewhen() {
+ String expr = "(CASE LSTG_FORMAT_NAME WHEN 'Auction' THEN 'x' WHEN 'y' THEN '222' ELSE 'z' END)";
+ String alias = "TEST_KYLIN_FACT";
+ String s = CalciteParser.insertAliasInExpr(expr, alias);
+ System.out.println(s);
+ assertEquals(
+ "(CASE TEST_KYLIN_FACT.LSTG_FORMAT_NAME WHEN 'Auction' THEN 'x' WHEN 'y' THEN '222' ELSE 'z' END)",
+ s);
+ }
+
+ @Test
public void testPos() throws SqlParseException {
String[] sqls = new String[] { "select \n a \n + \n b \n from t", //
"select\na\n+\nb\nfrom t", //
@@ -104,8 +116,8 @@ public class CalciteParserTest {
SqlNode sn2 = CalciteParser.getOnlySelectNode(sql2);
SqlNode sn3 = CalciteParser.getOnlySelectNode(sql3);
- Assert.assertEquals(true, CalciteParser.isNodeEqual(sn0, sn1));
- Assert.assertEquals(true, CalciteParser.isNodeEqual(sn0, sn2));
- Assert.assertEquals(false, CalciteParser.isNodeEqual(sn0, sn3));
+ assertEquals(true, CalciteParser.isNodeEqual(sn0, sn1));
+ assertEquals(true, CalciteParser.isNodeEqual(sn0, sn2));
+ assertEquals(false, CalciteParser.isNodeEqual(sn0, sn3));
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/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 7f188c1..a9ff360 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
@@ -24,8 +24,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.annotation.Nullable;
-
import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlDataTypeSpec;
import org.apache.calcite.sql.SqlDynamicParam;
@@ -40,18 +38,15 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.metadata.MetadataManager;
+import org.apache.kylin.metadata.model.ComputedColumnDesc;
import org.apache.kylin.metadata.model.DataModelDesc;
import org.apache.kylin.metadata.model.tool.CalciteParser;
-import org.apache.kylin.metadata.project.ProjectInstance;
-import org.apache.kylin.metadata.project.ProjectManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Functions;
-import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering;
public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
@@ -65,7 +60,7 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
ImmutableSortedMap<String, String> computedColumns = getSortedComputedColumnWithProject(project);
String s = replaceComputedColumn(sql, computedColumns);
if (!StringUtils.equals(sql, s)) {
- logger.debug("change sql to " + s);
+ logger.debug("sql changed");
}
return s;
}
@@ -162,28 +157,15 @@ public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
}
private ImmutableSortedMap<String, String> getSortedComputedColumnWithProject(String project) {
- MetadataManager metadataManager = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
- Map<String, MetadataManager.CCInfo> ccInfoMap = metadataManager.getCcInfoMap();
- final ProjectInstance projectInstance = ProjectManager.getInstance(KylinConfig.getInstanceFromEnv())
- .getProject(project);
-
- Iterable<MetadataManager.CCInfo> projectCCInfo = Iterables.filter(ccInfoMap.values(),
- new Predicate<MetadataManager.CCInfo>() {
- @Override
- public boolean apply(@Nullable MetadataManager.CCInfo ccInfo) {
- return Iterables.any(ccInfo.getDataModelDescs(), new Predicate<DataModelDesc>() {
- @Override
- public boolean apply(@Nullable DataModelDesc model) {
- return projectInstance.containsModel(model.getName());
- }
- });
- }
- });
Map<String, String> computedColumns = new HashMap<>();
- for (MetadataManager.CCInfo ccInfo : projectCCInfo) {
- computedColumns.put(ccInfo.getComputedColumnDesc().getColumnName(),
- ccInfo.getComputedColumnDesc().getExpression());
+
+ MetadataManager metadataManager = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
+ List<DataModelDesc> dataModelDescs = metadataManager.getModels(project);
+ for (DataModelDesc dataModelDesc : dataModelDescs) {
+ for (ComputedColumnDesc computedColumnDesc : dataModelDesc.getComputedColumnDescs()) {
+ computedColumns.put(computedColumnDesc.getColumnName(), computedColumnDesc.getExpression());
+ }
}
return getMapSortedByValue(computedColumns);
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java b/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
index 02b8e9f..79ed4aa 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
@@ -281,9 +281,7 @@ public class AclService implements MutableAclService {
} else {
aceInfos.addAll(allAceInfos.values());
}
- } else {
- logger.warn("Get null AllAceInfos from AclRecord");
- }
+ }
List<AccessControlEntry> newAces = new ArrayList<AccessControlEntry>();
for (int i = 0; i < aceInfos.size(); i++) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java b/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
index fa54eaa..89aee26 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
@@ -222,7 +222,7 @@ public class ModelService extends BasicService {
List<CubeInstance> cubes = cubeService.listAllCubes(null, null, modelName, true);
if (cubes != null && cubes.size() != 0) {
dataModelDesc.init(getConfig(), getMetadataManager().getAllTablesMap(),
- getMetadataManager().getCcInfoMap());
+ getMetadataManager().listDataModels());
List<String> dimCols = new ArrayList<String>();
List<String> dimAndMCols = new ArrayList<String>();
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java b/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
index 9694a21..0eff508 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
@@ -21,23 +21,18 @@ package org.apache.kylin.rest.util;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.annotation.Nullable;
-
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.ClassUtil;
import org.apache.kylin.metadata.MetadataManager;
-import org.apache.kylin.metadata.MetadataManager.CCInfo;
+import org.apache.kylin.metadata.model.ComputedColumnDesc;
import org.apache.kylin.metadata.model.DataModelDesc;
import org.apache.kylin.metadata.model.tool.CalciteParser;
-import org.apache.kylin.metadata.project.ProjectInstance;
-import org.apache.kylin.metadata.project.ProjectManager;
import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
import org.apache.kylin.query.routing.NoRealizationFoundException;
import org.apache.kylin.source.adhocquery.IAdHocConverter;
@@ -46,8 +41,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
public class AdHocUtil {
@@ -72,9 +65,13 @@ public class AdHocUtil {
logger.debug("Ad-hoc query runner {}", runner);
String expandCC = restoreComputedColumnToExpr(sql, project);
+ if (!StringUtils.equals(expandCC, sql)) {
+ logger.info("computed column in sql is expanded to: " + expandCC);
+ }
String adhocSql = converter.convert(expandCC);
- if (!adhocSql.equals(sql)) {
- logger.info("before delegating to adhoc, the query is converted to {} ", adhocSql);
+ if (!adhocSql.equals(expandCC)) {
+ logger.info("the query is converted to {} according to kylin.query.ad-hoc.converter-class-name",
+ adhocSql);
}
runner.executeQuery(adhocSql, results, columnMetas);
@@ -98,37 +95,22 @@ public class AdHocUtil {
private final static Pattern endWithAsPattern = Pattern.compile("\\s+as\\s+$", Pattern.CASE_INSENSITIVE);
public static String restoreComputedColumnToExpr(String beforeSql, String project) {
- MetadataManager metadataManager = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
- Map<String, CCInfo> ccInfoMap = metadataManager.getCcInfoMap();
- final ProjectInstance projectInstance = ProjectManager.getInstance(KylinConfig.getInstanceFromEnv())
- .getProject(project);
-
- Iterable<CCInfo> projectCCInfo = Iterables.filter(ccInfoMap.values(), new Predicate<CCInfo>() {
- @Override
- public boolean apply(@Nullable CCInfo ccInfo) {
- return Iterables.any(ccInfo.getDataModelDescs(), new Predicate<DataModelDesc>() {
- @Override
- public boolean apply(@Nullable DataModelDesc model) {
- return projectInstance.containsModel(model.getName());
- }
- });
- }
- });
+ final MetadataManager metadataManager = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
+ List<DataModelDesc> dataModelDescs = metadataManager.getModels(project);
String afterSql = beforeSql;
- for (CCInfo ccInfo : projectCCInfo) {
- afterSql = restoreComputedColumnToExpr(afterSql, ccInfo);
+ for (DataModelDesc dataModelDesc : dataModelDescs) {
+ for (ComputedColumnDesc computedColumnDesc : dataModelDesc.getComputedColumnDescs()) {
+ afterSql = restoreComputedColumnToExpr(afterSql, computedColumnDesc);
+ }
}
- if (!StringUtils.equals(beforeSql, afterSql)) {
- logger.info("computed column in sql is expanded before sending to adhoc engine: " + afterSql);
- }
return afterSql;
}
- static String restoreComputedColumnToExpr(String sql, CCInfo ccInfo) {
+ static String restoreComputedColumnToExpr(String sql, ComputedColumnDesc computedColumnDesc) {
- String ccName = ccInfo.getComputedColumnDesc().getColumnName();
+ String ccName = computedColumnDesc.getColumnName();
List<Triple<Integer, Integer, String>> replacements = Lists.newArrayList();
Matcher matcher = identifierInSqlPattern.matcher(sql);
@@ -146,14 +128,14 @@ public class AdHocUtil {
String quotedTableAlias = StringUtils.strip(matcher.group(2), ".");
String tableAlias = StringUtils.strip(quotedTableAlias, "\"");
replacements.add(Triple.of(matcher.start(1), matcher.end(1),
- replaceIdentifierInExpr(ccInfo.getComputedColumnDesc().getExpression(), tableAlias, true)));
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), tableAlias, true)));
} else { //only column
if (endWithAsPattern.matcher(sql.substring(0, matcher.start(1))).find()) {
//select DEAL_AMOUNT as "deal_amount" case
continue;
}
replacements.add(Triple.of(matcher.start(1), matcher.end(1),
- replaceIdentifierInExpr(ccInfo.getComputedColumnDesc().getExpression(), null, true)));
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), null, true)));
}
} else if (matcher.group(4) != null) { //without quote case: table.column or simply column
String columnName = matcher.group(6);
@@ -164,8 +146,8 @@ public class AdHocUtil {
if (matcher.group(5) != null) { //table name exist
String tableAlias = StringUtils.strip(matcher.group(5), ".");
- replacements.add(Triple.of(matcher.start(4), matcher.end(4), replaceIdentifierInExpr(
- ccInfo.getComputedColumnDesc().getExpression(), tableAlias, false)));
+ replacements.add(Triple.of(matcher.start(4), matcher.end(4),
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), tableAlias, false)));
} else { //only column
if (endWithAsPattern.matcher(sql.substring(0, matcher.start(4))).find()) {
@@ -173,7 +155,7 @@ public class AdHocUtil {
continue;
}
replacements.add(Triple.of(matcher.start(4), matcher.end(4),
- replaceIdentifierInExpr(ccInfo.getComputedColumnDesc().getExpression(), null, false)));
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), null, false)));
}
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
----------------------------------------------------------------------
diff --git a/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java b/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
index 724844c..05b135a 100644
--- a/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
+++ b/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
@@ -17,7 +17,6 @@
*/
package org.apache.kylin.rest.util;
-import static org.apache.kylin.metadata.MetadataManager.CCInfo;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -62,36 +61,34 @@ public class AdHocUtilTest {
when(computedColumnDesc.getColumnName()).thenReturn("DEAL_AMOUNT");
when(computedColumnDesc.getExpression()).thenReturn("price * number");
- CCInfo ccInfo = mock(CCInfo.class);
- when(ccInfo.getComputedColumnDesc()).thenReturn(computedColumnDesc);
-
{
String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT", ccInfo);
- Assert.assertEquals(
- "select (price * number) from DB.TABLE group by date order by (price * number)",
- ret);
+ "select DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT", computedColumnDesc);
+ Assert.assertEquals("select (price * number) from DB.TABLE group by date order by (price * number)", ret);
}
{
String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select DEAL_AMOUNT as DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT", ccInfo);
+ "select DEAL_AMOUNT as DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT",
+ computedColumnDesc);
Assert.assertEquals(
"select (price * number) as DEAL_AMOUNT from DB.TABLE group by date order by (price * number)",
ret);
}
{
String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select \"DEAL_AMOUNT\" AS deal_amount from DB.TABLE group by date order by DEAL_AMOUNT", ccInfo);
+ "select \"DEAL_AMOUNT\" AS deal_amount from DB.TABLE group by date order by DEAL_AMOUNT",
+ computedColumnDesc);
Assert.assertEquals(
"select (price * number) AS deal_amount from DB.TABLE group by date order by (price * number)",
ret);
}
{
String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select x.DEAL_AMOUNT AS deal_amount from DB.TABLE x group by date order by x.DEAL_AMOUNT", ccInfo);
+ "select x.DEAL_AMOUNT AS deal_amount from DB.TABLE x group by date order by x.DEAL_AMOUNT",
+ computedColumnDesc);
Assert.assertEquals(
- "select (x.price * x.number) AS deal_amount from DB.TABLE x group by date order by (x.price * x.number)",
- ret);
+ "select (x.price * x.number) AS deal_amount from DB.TABLE x group by date order by (x.price * x.number)",
+ ret);
}
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf1ba956/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java b/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
index b78b18e..b8633fb 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
@@ -80,8 +80,8 @@ public class ModelServiceTest extends ServiceTestBase {
@Test
public void testFailureModelUpdateDueToComputedColumnConflict() throws IOException, JobException, NoSuchFieldException, IllegalAccessException {
- expectedEx.expect(IllegalStateException.class);
- expectedEx.expectMessage("Computed column named DEFAULT.TEST_KYLIN_FACT.DEAL_AMOUNT is already defined in other models: [DataModelDesc [name=ci_left_join_model], DataModelDesc [name=ci_inner_join_model]]. Please change another name, or try to keep consistent definition");
+ expectedEx.expect(IllegalArgumentException.class);
+ expectedEx.expectMessage("Computed column named DEFAULT.TEST_KYLIN_FACT.DEAL_AMOUNT is defined differently in model ci_inner_join_model");
List<DataModelDesc> dataModelDescs = modelService.listAllModels("ci_left_join_model", "default", true);
Assert.assertTrue(dataModelDescs.size() == 1);
[04/26] kylin git commit: fix ci
Posted by li...@apache.org.
fix ci
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/86032971
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/86032971
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/86032971
Branch: refs/heads/kylin-2.1.x
Commit: 86032971f766a893a28fce9017227999f5defe2d
Parents: 56a0fa5
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 29 11:46:04 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 29 13:51:45 2017 +0800
----------------------------------------------------------------------
.../query/sql_computedcolumn/query03.sql | 21 ++++++++++++++++++++
.../sql_computedcolumn/query03.sql.compare | 21 ++++++++++++++++++++
.../org/apache/kylin/rest/util/AdHocUtil.java | 19 ++++--------------
3 files changed, 46 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/86032971/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql b/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql
new file mode 100644
index 0000000..ff8a570
--- /dev/null
+++ b/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql
@@ -0,0 +1,21 @@
+SELECT
+
+count(*) as cnt, sum(price) as sum_price, sum(DEAL_AMOUNT) as deal_amount, SELLER_COUNTRY.NAME, DEAL_YEAR as deal_year
+
+FROM TEST_KYLIN_FACT as TEST_KYLIN_FACT
+INNER JOIN TEST_ORDER as TEST_ORDER
+ON TEST_KYLIN_FACT.ORDER_ID = TEST_ORDER.ORDER_ID
+INNER JOIN TEST_ACCOUNT as BUYER_ACCOUNT
+ON TEST_ORDER.BUYER_ID = BUYER_ACCOUNT.ACCOUNT_ID
+INNER JOIN TEST_ACCOUNT as SELLER_ACCOUNT
+ON TEST_KYLIN_FACT.SELLER_ID = SELLER_ACCOUNT.ACCOUNT_ID
+INNER JOIN TEST_CATEGORY_GROUPINGS as TEST_CATEGORY_GROUPINGS
+ON TEST_KYLIN_FACT.LEAF_CATEG_ID = TEST_CATEGORY_GROUPINGS.LEAF_CATEG_ID AND TEST_KYLIN_FACT.LSTG_SITE_ID = TEST_CATEGORY_GROUPINGS.SITE_ID
+INNER JOIN TEST_COUNTRY as BUYER_COUNTRY
+ON BUYER_ACCOUNT.ACCOUNT_COUNTRY = BUYER_COUNTRY.COUNTRY
+INNER JOIN TEST_COUNTRY as SELLER_COUNTRY
+ON SELLER_ACCOUNT.ACCOUNT_COUNTRY = SELLER_COUNTRY.COUNTRY
+
+
+where SELLER_ACCOUNT.ACCOUNT_SELLER_LEVEL=1 and "SELLER_ACCOUNT"."COUNTRY_ABBR" in ('T', 'R') and BUYER_ACCOUNT.COUNTRY_ABBR in ('T', 'R')
+group by SELLER_COUNTRY.NAME, DEAL_YEAR
http://git-wip-us.apache.org/repos/asf/kylin/blob/86032971/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql.compare
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql.compare b/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql.compare
new file mode 100644
index 0000000..160375c
--- /dev/null
+++ b/kylin-it/src/test/resources/query/sql_computedcolumn/query03.sql.compare
@@ -0,0 +1,21 @@
+SELECT
+
+count(*) as cnt, sum(price) as sum_price, sum(TEST_KYLIN_FACT.PRICE * TEST_KYLIN_FACT.ITEM_COUNT) as deal_amount, SELLER_COUNTRY.NAME, year(TEST_KYLIN_FACT.CAL_DT) as deal_year
+
+FROM TEST_KYLIN_FACT as TEST_KYLIN_FACT
+INNER JOIN TEST_ORDER as TEST_ORDER
+ON TEST_KYLIN_FACT.ORDER_ID = TEST_ORDER.ORDER_ID
+INNER JOIN TEST_ACCOUNT as BUYER_ACCOUNT
+ON TEST_ORDER.BUYER_ID = BUYER_ACCOUNT.ACCOUNT_ID
+INNER JOIN TEST_ACCOUNT as SELLER_ACCOUNT
+ON TEST_KYLIN_FACT.SELLER_ID = SELLER_ACCOUNT.ACCOUNT_ID
+INNER JOIN TEST_CATEGORY_GROUPINGS as TEST_CATEGORY_GROUPINGS
+ON TEST_KYLIN_FACT.LEAF_CATEG_ID = TEST_CATEGORY_GROUPINGS.LEAF_CATEG_ID AND TEST_KYLIN_FACT.LSTG_SITE_ID = TEST_CATEGORY_GROUPINGS.SITE_ID
+INNER JOIN TEST_COUNTRY as BUYER_COUNTRY
+ON BUYER_ACCOUNT.ACCOUNT_COUNTRY = BUYER_COUNTRY.COUNTRY
+INNER JOIN TEST_COUNTRY as SELLER_COUNTRY
+ON SELLER_ACCOUNT.ACCOUNT_COUNTRY = SELLER_COUNTRY.COUNTRY
+
+
+where SELLER_ACCOUNT.ACCOUNT_SELLER_LEVEL=1 and SUBSTR("SELLER_ACCOUNT"."ACCOUNT_COUNTRY",1,1) in ('T', 'R') and SUBSTR(BUYER_ACCOUNT.ACCOUNT_COUNTRY,1,1) in ('T', 'R')
+group by SELLER_COUNTRY.NAME, year(TEST_KYLIN_FACT.CAL_DT)
http://git-wip-us.apache.org/repos/asf/kylin/blob/86032971/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java b/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
index 9eecdc1..9694a21 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
@@ -35,6 +35,7 @@ import org.apache.kylin.common.util.ClassUtil;
import org.apache.kylin.metadata.MetadataManager;
import org.apache.kylin.metadata.MetadataManager.CCInfo;
import org.apache.kylin.metadata.model.DataModelDesc;
+import org.apache.kylin.metadata.model.tool.CalciteParser;
import org.apache.kylin.metadata.project.ProjectInstance;
import org.apache.kylin.metadata.project.ProjectManager;
import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
@@ -185,23 +186,11 @@ public class AdHocUtil {
return sql;
}
- // identifier in expr must be DB.TABLE.COLUMN, all TABLE in expr should be guaranteed to be same
static String replaceIdentifierInExpr(String expr, String tableAlias, boolean quoted) {
- List<Triple<Integer, Integer, String>> replacements = Lists.newArrayList();
- Matcher matcher = identifierInExprPattern.matcher(expr);
- while (matcher.find()) {
-
- String t = tableAlias == null ? StringUtils.strip(matcher.group(3), ".") : tableAlias;
- String c = matcher.group(4);
-
- String replacement = quoted ? "\"" + t.toUpperCase() + "\".\"" + c.toUpperCase() + "\"" : t + "." + c;
- replacements.add(Triple.of(matcher.start(1), matcher.end(1), replacement));
+ if (tableAlias == null) {
+ return expr;
}
- Collections.reverse(replacements);
- for (Triple<Integer, Integer, String> triple : replacements) {
- expr = expr.substring(0, triple.getLeft()) + triple.getRight() + expr.substring(triple.getMiddle());
- }
- return expr;
+ return CalciteParser.insertAliasInExpr(expr, tableAlias);
}
}
[14/26] kylin git commit: KYLIN-2696 Check SQL injection in filter
condition
Posted by li...@apache.org.
KYLIN-2696 Check SQL injection in filter condition
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/2546e00c
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/2546e00c
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/2546e00c
Branch: refs/heads/kylin-2.1.x
Commit: 2546e00cf2f80b0f8abba9ec3cfe9a0fbce5cb4f
Parents: e7f9dab
Author: Xiaqing <45...@qq.com>
Authored: Fri Jun 30 09:42:07 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 30 09:42:07 2017 +0800
----------------------------------------------------------------------
.../kylin/metadata/model/DataModelDesc.java | 43 ++++++++++++++++++++
1 file changed, 43 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/2546e00c/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
index 91802f7..341f36e 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
@@ -352,6 +352,7 @@ public class DataModelDesc extends RootPersistentEntity {
initDimensionsAndMetrics();
initPartitionDesc();
initComputedColumns(ccInfoMap);
+ initFilterCondition();
boolean reinit = validate();
if (reinit) { // model slightly changed by validate() and must init() again
@@ -505,6 +506,48 @@ public class DataModelDesc extends RootPersistentEntity {
}
}
+ //Check if the filter condition is illegal.
+ private void initFilterCondition() {
+ if (null == this.filterCondition) {
+ return;
+ }
+ int quotationType = 0;
+ int len = this.filterCondition.length();
+ for (int i = 0; i < len; i++) {
+ //If a ';' which is not within a string is found, throw exception.
+ if (';' == this.filterCondition.charAt(i) && 0 == quotationType) {
+ throw new IllegalStateException(
+ "Filter Condition is Illegal. Please check it and make sure it's an appropriate expression for WHERE clause");
+ }
+ if ('\'' == this.filterCondition.charAt(i)) {
+ if (quotationType > 0) {
+ if (1 == quotationType) {
+ quotationType = 0;
+ continue;
+ }
+ } else {
+ if (0 == quotationType) {
+ quotationType = 1;
+ continue;
+ }
+ }
+ }
+ if ('"' == this.filterCondition.charAt(i)) {
+ if (quotationType > 0) {
+ if (2 == quotationType) {
+ quotationType = 0;
+ continue;
+ }
+ } else {
+ if (0 == quotationType) {
+ quotationType = 2;
+ continue;
+ }
+ }
+ }
+ }
+ }
+
private void checkSameCCDefinition(Map<String, CCInfo> ccInfoMap, ComputedColumnDesc thisCCDesc,
String thisCCName) {
//check whether two computer columns's definition is the same.
[16/26] kylin git commit: minor, fix project rename bug (#1475)
Posted by li...@apache.org.
minor, fix project rename bug (#1475)
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/5fb4f350
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/5fb4f350
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/5fb4f350
Branch: refs/heads/kylin-2.1.x
Commit: 5fb4f3500d12e3ad160b2235667de6131907af57
Parents: f52eb0c
Author: Roger Shi <ro...@gmail.com>
Authored: Fri Jun 30 14:31:24 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 30 14:31:24 2017 +0800
----------------------------------------------------------------------
.../src/main/java/org/apache/kylin/rest/service/ProjectService.java | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/5fb4f350/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java b/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
index c6bd6cf..cd60128 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
@@ -121,6 +121,7 @@ public class ProjectService extends BasicService {
// rebind draft and project
for (Draft draft : getDraftManager().list(currentProject.getName())) {
draft.setProject(newProjectName);
+ getDraftManager().save(draft);
}
logger.debug("Project rename.");
[09/26] kylin git commit: #476 enable model read permission when
grant cube permissions
Posted by li...@apache.org.
#476 enable model read permission when grant cube permissions
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/8ca0d321
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/8ca0d321
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/8ca0d321
Branch: refs/heads/kylin-2.1.x
Commit: 8ca0d3217453929d0ac0c3078d9e78e769f852b0
Parents: 7f79083
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 29 17:23:13 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Thu Jun 29 18:05:01 2017 +0800
----------------------------------------------------------------------
.../kylin/rest/controller2/AccessControllerV2.java | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/8ca0d321/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
index 1ca8652..bd7d897 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
@@ -21,12 +21,15 @@ package org.apache.kylin.rest.controller2;
import java.io.IOException;
import org.apache.kylin.common.persistence.AclEntity;
+import org.apache.kylin.cube.CubeInstance;
import org.apache.kylin.rest.controller.BasicController;
import org.apache.kylin.rest.request.AccessRequest;
import org.apache.kylin.rest.response.EnvelopeResponse;
import org.apache.kylin.rest.response.ResponseCode;
+import org.apache.kylin.rest.security.AclEntityType;
import org.apache.kylin.rest.security.AclPermissionFactory;
import org.apache.kylin.rest.service.AccessService;
+import org.apache.kylin.rest.service.CubeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.acls.model.Acl;
@@ -51,6 +54,10 @@ public class AccessControllerV2 extends BasicController {
@Qualifier("accessService")
private AccessService accessService;
+ @Autowired
+ @Qualifier("cubeMgmtService")
+ private CubeService cubeService;
+
/**
* Get access entry list of a domain object
*
@@ -100,6 +107,15 @@ public class AccessControllerV2 extends BasicController {
Permission permission = AclPermissionFactory.getPermission(accessRequest.getPermission());
Acl acl = accessService.grant(ae, permission, sid);
+ if (AclEntityType.CUBE_INSTANCE.equals(type)) {
+ CubeInstance instance = cubeService.getCubeManager().getCubeByUuid(uuid);
+ if (instance != null) {
+ AclEntity model = accessService.getAclEntity(AclEntityType.DATA_MODEL_DESC, instance.getModel().getUuid());
+ // FIXME: should not always grant
+ accessService.grant(model, permission, sid);
+ }
+ }
+
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, accessService.generateAceResponses(acl), "");
}
[02/26] kylin git commit: update pom
Posted by li...@apache.org.
update pom
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/56a0fa5f
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/56a0fa5f
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/56a0fa5f
Branch: refs/heads/kylin-2.1.x
Commit: 56a0fa5f1d1bebde0297612ee9a4af0354ce672e
Parents: d61f867
Author: Hongbin Ma <ma...@apache.org>
Authored: Wed Jun 28 21:30:52 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 29 13:51:45 2017 +0800
----------------------------------------------------------------------
core-metadata/pom.xml | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/56a0fa5f/core-metadata/pom.xml
----------------------------------------------------------------------
diff --git a/core-metadata/pom.xml b/core-metadata/pom.xml
index d45a838..9e06ecf 100644
--- a/core-metadata/pom.xml
+++ b/core-metadata/pom.xml
@@ -70,9 +70,6 @@
<artifactId>avatica-core</artifactId>
</exclusion>
</exclusions>
- <!--set to provided on purpose, so that dependant on metadata module will not depend on calcite unnecessarily-->
- <!--https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html-->
- <scope>provided</scope>
</dependency>
<!-- Compiled -->
[19/26] kylin git commit: minor, refine drop job situation
Posted by li...@apache.org.
minor, refine drop job situation
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/03702f1e
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/03702f1e
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/03702f1e
Branch: refs/heads/kylin-2.1.x
Commit: 03702f1ecd3a79228468bb7ec6ae25ad369fd65c
Parents: 6228f88
Author: Cheng Wang <ch...@kyligence.io>
Authored: Fri Jun 30 19:19:35 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 30 19:21:45 2017 +0800
----------------------------------------------------------------------
.../java/org/apache/kylin/rest/controller2/JobControllerV2.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/03702f1e/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
index a86082c..5a18e66 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
@@ -282,8 +282,7 @@ public class JobControllerV2 extends BasicController {
JobInstance jobInstance = jobService.getJobInstance(jobId);
JobStatusEnum status = jobInstance.getStatus();
- if (status == JobStatusEnum.NEW || status == JobStatusEnum.PENDING || status == JobStatusEnum.RUNNING
- || status == JobStatusEnum.STOPPED) {
+ if (status != JobStatusEnum.FINISHED && status != JobStatusEnum.DISCARDED) {
throw new BadRequestException(
"Cannot drop running job " + jobInstance.getName() + ", please discard it first.");
}
[05/26] kylin git commit: Minor change, format code
Posted by li...@apache.org.
Minor change, format code
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/c8acbc62
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/c8acbc62
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/c8acbc62
Branch: refs/heads/kylin-2.1.x
Commit: c8acbc620b2e52fd9d2ba3fc6fc478a6418b0f97
Parents: 2f7aa45
Author: auphyroc99 <45...@qq.com>
Authored: Thu Jun 29 14:48:38 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 29 14:50:21 2017 +0800
----------------------------------------------------------------------
.../java/org/apache/kylin/jdbc/DriverTest.java | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/c8acbc62/jdbc/src/test/java/org/apache/kylin/jdbc/DriverTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/kylin/jdbc/DriverTest.java b/jdbc/src/test/java/org/apache/kylin/jdbc/DriverTest.java
index 4fd9d33..70978d7 100644
--- a/jdbc/src/test/java/org/apache/kylin/jdbc/DriverTest.java
+++ b/jdbc/src/test/java/org/apache/kylin/jdbc/DriverTest.java
@@ -178,7 +178,8 @@ public class DriverTest {
info.put("password", "KYLIN");
Connection conn = driver.connect("jdbc:kylin://localhost:7070/default", info);
- PreparedStatement state = conn.prepareStatement("select cal_dt, count(*) from test_kylin_fact where seller_id=? group by cal_dt");
+ PreparedStatement state = conn
+ .prepareStatement("select cal_dt, count(*) from test_kylin_fact where seller_id=? group by cal_dt");
state.setLong(1, 10000001);
ResultSet resultSet = state.executeQuery();
@@ -189,14 +190,14 @@ public class DriverTest {
state.close();
conn.close();
}
-
+
@Test
- public void testSSLFromURL() throws SQLException{
+ public void testSSLFromURL() throws SQLException {
Driver driver = new DummyDriver();
Connection conn = driver.connect("jdbc:kylin:ssl=True;//test_url/test_db", null);
- assertEquals("test_url", ((KylinConnection)conn).getBaseUrl());
- assertEquals("test_db", ((KylinConnection)conn).getProject());
- assertTrue(Boolean.parseBoolean( (String)((KylinConnection)conn).getConnectionProperties().get("ssl")));
+ assertEquals("test_url", ((KylinConnection) conn).getBaseUrl());
+ assertEquals("test_db", ((KylinConnection) conn).getProject());
+ assertTrue(Boolean.parseBoolean((String) ((KylinConnection) conn).getConnectionProperties().get("ssl")));
}
private void printResultSet(ResultSet rs) throws SQLException {
@@ -221,7 +222,12 @@ public class DriverTest {
System.out.println("Metadata:");
for (int i = 0; i < metadata.getColumnCount(); i++) {
- String metaStr = metadata.getCatalogName(i + 1) + " " + metadata.getColumnClassName(i + 1) + " " + metadata.getColumnDisplaySize(i + 1) + " " + metadata.getColumnLabel(i + 1) + " " + metadata.getColumnName(i + 1) + " " + metadata.getColumnType(i + 1) + " " + metadata.getColumnTypeName(i + 1) + " " + metadata.getPrecision(i + 1) + " " + metadata.getScale(i + 1) + " " + metadata.getSchemaName(i + 1) + " " + metadata.getTableName(i + 1);
+ String metaStr = metadata.getCatalogName(i + 1) + " " + metadata.getColumnClassName(i + 1) + " "
+ + metadata.getColumnDisplaySize(i + 1) + " " + metadata.getColumnLabel(i + 1) + " "
+ + metadata.getColumnName(i + 1) + " " + metadata.getColumnType(i + 1) + " "
+ + metadata.getColumnTypeName(i + 1) + " " + metadata.getPrecision(i + 1) + " "
+ + metadata.getScale(i + 1) + " " + metadata.getSchemaName(i + 1) + " "
+ + metadata.getTableName(i + 1);
System.out.println(metaStr);
}
}
[12/26] kylin git commit: minor, fix agg combination bug
Posted by li...@apache.org.
minor, fix agg combination bug
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/5eca7f6b
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/5eca7f6b
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/5eca7f6b
Branch: refs/heads/kylin-2.1.x
Commit: 5eca7f6b59454df4681deb17f361d4708a2affca
Parents: 40054dd
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 29 23:07:16 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Thu Jun 29 23:11:00 2017 +0800
----------------------------------------------------------------------
.../main/java/org/apache/kylin/cube/model/AggregationGroup.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/5eca7f6b/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
----------------------------------------------------------------------
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java b/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
index 064d657..0533ea1 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
@@ -320,7 +320,7 @@ public class AggregationGroup implements Serializable {
normalDims.removeAll(jointDims);
combination = combination * (1L << normalDims.size());
- if (cubeDesc.getConfig().getCubeAggrGroupIsMandatoryOnlyValid()) {
+ if (cubeDesc.getConfig().getCubeAggrGroupIsMandatoryOnlyValid() && !mandatoryDims.isEmpty()) {
combination += 1;
}
combination -= 1; // not include cuboid 0
[25/26] kylin git commit: minor, fix acl migrate tool
Posted by li...@apache.org.
minor, fix acl migrate tool
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/4f4382df
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/4f4382df
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/4f4382df
Branch: refs/heads/kylin-2.1.x
Commit: 4f4382df90ddd04a963dda36bcc1093c4b5d77b4
Parents: 7002dd8
Author: Roger Shi <ro...@hotmail.com>
Authored: Fri Jun 30 23:40:42 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 30 23:45:52 2017 +0800
----------------------------------------------------------------------
.../org/apache/kylin/rest/service/AclTableMigrationTool.java | 4 ++--
.../src/main/java/org/apache/kylin/rest/service/CubeService.java | 2 --
2 files changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f4382df/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
index 029efdc..bb07c22 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
@@ -224,8 +224,8 @@ public class AclTableMigrationTool {
Map<String, AceInfo> allAceInfoMap = new HashMap<>();
NavigableMap<byte[], byte[]> familyMap = result.getFamilyMap(Bytes.toBytes(AclConstant.ACL_ACES_FAMILY));
for (Map.Entry<byte[], byte[]> entry : familyMap.entrySet()) {
- String sid = String.valueOf(entry.getKey());
- AceInfo aceInfo = aceSerializer.deserialize(familyMap.get(entry.getValue()));
+ String sid = new String(entry.getKey());
+ AceInfo aceInfo = aceSerializer.deserialize(entry.getValue());
if (null != aceInfo) {
allAceInfoMap.put(sid, aceInfo);
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f4382df/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java b/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
index b2e44f6..aa42cb0 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
@@ -659,8 +659,6 @@ public class CubeService extends BasicService {
getDraftManager().save(draft);
}
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN
- + " or hasPermission(#draft, 'ADMINISTRATION') or hasPermission(#draft, 'MANAGEMENT')")
public void deleteDraft(Draft draft) throws IOException {
getDraftManager().delete(draft.getUuid());
}
[20/26] kylin git commit: Use calcite's keywords during subquery
convert.
Posted by li...@apache.org.
Use calcite's keywords during subquery convert.
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/dc232d11
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/dc232d11
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/dc232d11
Branch: refs/heads/kylin-2.1.x
Commit: dc232d114c5ad8c50ebed60cf238a0f5b21802a8
Parents: 03702f1
Author: nichunen <ch...@kyligence.io>
Authored: Fri Jun 30 19:43:53 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 30 19:57:28 2017 +0800
----------------------------------------------------------------------
.../source/adhocquery/HiveAdhocConverter.java | 102 ++++++++++++++-----
1 file changed, 79 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/dc232d11/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
index 89b2f7a..e8c06ff 100644
--- a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
+++ b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
@@ -45,29 +45,85 @@ public class HiveAdhocConverter implements IAdHocConverter {
Pattern.CASE_INSENSITIVE);
private static final Pattern TIMESTAMPADD_PATTERN = Pattern.compile("timestampadd\\s*\\(\\s*(.*?)\\s*,",
Pattern.CASE_INSENSITIVE);
- private static final ImmutableSet<String> sqlKeyWordsExceptAS = ImmutableSet.of("ABSOLUTE", "ACTION", "ADD", "ALL",
- "ALLOCATE", "ALTER", "AND", "ANY", "ARE", "ASC", "ASSERTION", "AT", "AUTHORIZATION", "AVG", "BEGIN",
- "BETWEEN", "BIT", "BIT_LENGTH", "BOTH", "BY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG", "CHAR",
- "CHARACTER", "CHARACTER_LENGTH", "CHAR_LENGTH", "CHECK", "CLOSE", "COALESCE", "COLLATE", "COLLATION",
- "COLUMN", "COMMIT", "CONNECT", "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONTINUE", "CONVERT",
- "CORRESPONDING", "COUNT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
- "CURRENT_USER", "CURSOR", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFERRABLE",
- "DEFERRED", "DELETE", "DESC", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DISCONNECT", "DISTINCT", "DOMAIN",
- "DOUBLE", "DROP", "ELSE", "END", "END-EXEC", "ESCAPE", "EXCEPT", "EXCEPTION", "EXEC", "EXECUTE", "EXISTS",
- "EXTERNAL", "EXTRACT", "FALSE", "FETCH", "FIRST", "FLOAT", "FOR", "FOREIGN", "FOUND", "FROM", "FULL", "GET",
- "GLOBAL", "GO", "GOTO", "GRANT", "GROUP", "HAVING", "HOUR", "IDENTITY", "IMMEDIATE", "IN", "INDICATOR",
- "INITIALLY", "INNER", "INADD", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTERSECT", "INTERVAL", "INTO",
- "IS", "ISOLATION", "JOIN", "KEY", "LANGUAGE", "LAST", "LEADING", "LEFT", "LEVEL", "LIKE", "LOCAL", "LOWER",
- "MATCH", "MAX", "MIN", "MINUTE", "MODULE", "MONTH", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NEXT", "NO",
- "NOT", "NULL", "NULLIF", "NUMERIC", "OCTET_LENGTH", "OF", "ON", "ONLY", "OPEN", "OPTION", "OR", "ORDER",
- "OUTER", "OUTADD", "OVERLAPS", "PAD", "PARTIAL", "POSITION", "PRECISION", "PREPARE", "PRESERVE", "PRIMARY",
- "PRIOR", "PRIVILEGES", "PROCEDURE", "PUBLIC", "READ", "REAL", "REFERENCES", "RELATIVE", "RESTRICT",
- "REVOKE", "RIGHT", "ROLLBACK", "ROWS", "SCHEMA", "SCROLL", "SECOND", "SECTION", "SELECT", "SESSION",
- "SESSION_USER", "SET", "SIZE", "SMALLINT", "SOME", "SPACE", "SQL", "SQLCODE", "SQLERROR", "SQLSTATE",
- "SUBSTRING", "SUM", "SYSTEM_USER", "TABLE", "TEMPORARY", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR",
- "TIMEZONE_MINUTE", "TO", "TRAILING", "TRANSACTION", "TRANSLATE", "TRANSLATION", "TRIM", "TRUE", "UNION",
- "UNIQUE", "UNKNOWN", "UPDATE", "UPPER", "USAGE", "USER", "USING", "VALUE", "VALUES", "VARCHAR", "VARYING",
- "VIEW", "WHEN", "WHENEVER", "WHERE", "WITH", "WORK", "WRITE", "YEAR", "ZONE");
+ private static final ImmutableSet<String> sqlKeyWordsExceptAS = ImmutableSet.of("A", "ABS", "ABSOLUTE", "ACTION",
+ "ADA", "ADD", "ADMIN", "AFTER", "ALL", "ALLOCATE", "ALLOW", "ALTER", "ALWAYS", "AND", "ANY", "APPLY", "ARE",
+ "ARRAY", "ARRAY_MAX_CARDINALITY", "ASC", "ASENSITIVE", "ASSERTION", "ASSIGNMENT", "ASYMMETRIC", "AT",
+ "ATOMIC", "ATTRIBUTE", "ATTRIBUTES", "AUTHORIZATION", "AVG", "BEFORE", "BEGIN", "BEGIN_FRAME",
+ "BEGIN_PARTITION", "BERNOULLI", "BETWEEN", "BIGINT", "BINARY", "BIT", "BLOB", "BOOLEAN", "BOTH", "BREADTH",
+ "BY", "C", "CALL", "CALLED", "CARDINALITY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG",
+ "CATALOG_NAME", "CEIL", "CEILING", "CENTURY", "CHAIN", "CHAR", "CHARACTER", "CHARACTERISTICS", "CHARACTERS",
+ "CHARACTER_LENGTH", "CHARACTER_SET_CATALOG", "CHARACTER_SET_NAME", "CHARACTER_SET_SCHEMA", "CHAR_LENGTH",
+ "CHECK", "CLASSIFIER", "CLASS_ORIGIN", "CLOB", "CLOSE", "COALESCE", "COBOL", "COLLATE", "COLLATION",
+ "COLLATION_CATALOG", "COLLATION_NAME", "COLLATION_SCHEMA", "COLLECT", "COLUMN", "COLUMN_NAME",
+ "COMMAND_FUNCTION", "COMMAND_FUNCTION_CODE", "COMMIT", "COMMITTED", "CONDITION", "CONDITION_NUMBER",
+ "CONNECT", "CONNECTION", "CONNECTION_NAME", "CONSTRAINT", "CONSTRAINTS", "CONSTRAINT_CATALOG",
+ "CONSTRAINT_NAME", "CONSTRAINT_SCHEMA", "CONSTRUCTOR", "CONTAINS", "CONTINUE", "CONVERT", "CORR",
+ "CORRESPONDING", "COUNT", "COVAR_POP", "COVAR_SAMP", "CREATE", "CROSS", "CUBE", "CUME_DIST", "CURRENT",
+ "CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_DEFAULT_TRANSFORM_GROUP", "CURRENT_PATH", "CURRENT_ROLE",
+ "CURRENT_ROW", "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_TRANSFORM_GROUP_FOR_TYPE",
+ "CURRENT_USER", "CURSOR", "CURSOR_NAME", "CYCLE", "DATA", "DATABASE", "DATE", "DATETIME_INTERVAL_CODE",
+ "DATETIME_INTERVAL_PRECISION", "DAY", "DEALLOCATE", "DEC", "DECADE", "DECIMAL", "DECLARE", "DEFAULT",
+ "DEFAULTS", "DEFERRABLE", "DEFERRED", "DEFINE", "DEFINED", "DEFINER", "DEGREE", "DELETE", "DENSE_RANK",
+ "DEPTH", "DEREF", "DERIVED", "DESC", "DESCRIBE", "DESCRIPTION", "DESCRIPTOR", "DETERMINISTIC",
+ "DIAGNOSTICS", "DISALLOW", "DISCONNECT", "DISPATCH", "DISTINCT", "DOMAIN", "DOUBLE", "DOW", "DOY", "DROP",
+ "DYNAMIC", "DYNAMIC_FUNCTION", "DYNAMIC_FUNCTION_CODE", "EACH", "ELEMENT", "ELSE", "EMPTY", "END",
+ "END-EXEC", "END_FRAME", "END_PARTITION", "EPOCH", "EQUALS", "ESCAPE", "EVERY", "EXCEPT", "EXCEPTION",
+ "EXCLUDE", "EXCLUDING", "EXEC", "EXECUTE", "EXISTS", "EXP", "EXPLAIN", "EXTEND", "EXTERNAL", "EXTRACT",
+ "FALSE", "FETCH", "FILTER", "FINAL", "FIRST", "FIRST_VALUE", "FLOAT", "FLOOR", "FOLLOWING", "FOR",
+ "FOREIGN", "FORTRAN", "FOUND", "FRAC_SECOND", "FRAME_ROW", "FREE", "FROM", "FULL", "FUNCTION", "FUSION",
+ "G", "GENERAL", "GENERATED", "GET", "GLOBAL", "GO", "GOTO", "GRANT", "GRANTED", "GROUP", "GROUPING",
+ "GROUPS", "HAVING", "HIERARCHY", "HOLD", "HOUR", "IDENTITY", "IMMEDIATE", "IMMEDIATELY", "IMPLEMENTATION",
+ "IMPORT", "IN", "INCLUDING", "INCREMENT", "INDICATOR", "INITIAL", "INITIALLY", "INNER", "INOUT", "INPUT",
+ "INSENSITIVE", "INSERT", "INSTANCE", "INSTANTIABLE", "INT", "INTEGER", "INTERSECT", "INTERSECTION",
+ "INTERVAL", "INTO", "INVOKER", "IS", "ISOLATION", "JAVA", "JOIN", "JSON", "K", "KEY", "KEY_MEMBER",
+ "KEY_TYPE", "LABEL", "LAG", "LANGUAGE", "LARGE", "LAST", "LAST_VALUE", "LATERAL", "LEAD", "LEADING", "LEFT",
+ "LENGTH", "LEVEL", "LIBRARY", "LIKE", "LIKE_REGEX", "LIMIT", "LN", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP",
+ "LOCATOR", "LOWER", "M", "MAP", "MATCH", "MATCHED", "MATCHES", "MATCH_NUMBER", "MATCH_RECOGNIZE", "MAX",
+ "MAXVALUE", "MEASURES", "MEMBER", "MERGE", "MESSAGE_LENGTH", "MESSAGE_OCTET_LENGTH", "MESSAGE_TEXT",
+ "METHOD", "MICROSECOND", "MILLENNIUM", "MIN", "MINUS", "MINUTE", "MINVALUE", "MOD", "MODIFIES", "MODULE",
+ "MONTH", "MORE", "MULTISET", "MUMPS", "NAME", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NCLOB", "NESTING",
+ "NEW", "NEXT", "NO", "NONE", "NORMALIZE", "NORMALIZED", "NOT", "NTH_VALUE", "NTILE", "NULL", "NULLABLE",
+ "NULLIF", "NULLS", "NUMBER", "NUMERIC", "OBJECT", "OCCURRENCES_REGEX", "OCTETS", "OCTET_LENGTH", "OF",
+ "OFFSET", "OLD", "OMIT", "ON", "ONE", "ONLY", "OPEN", "OPTION", "OPTIONS", "OR", "ORDER", "ORDERING",
+ "ORDINALITY", "OTHERS", "OUT", "OUTER", "OUTPUT", "OVER", "OVERLAPS", "OVERLAY", "OVERRIDING", "PAD",
+ "PARAMETER", "PARAMETER_MODE", "PARAMETER_NAME", "PARAMETER_ORDINAL_POSITION", "PARAMETER_SPECIFIC_CATALOG",
+ "PARAMETER_SPECIFIC_NAME", "PARAMETER_SPECIFIC_SCHEMA", "PARTIAL", "PARTITION", "PASCAL", "PASSTHROUGH",
+ "PAST", "PATH", "PATTERN", "PER", "PERCENT", "PERCENTILE_CONT", "PERCENTILE_DISC", "PERCENT_RANK", "PERIOD",
+ "PERMUTE", "PLACING", "PLAN", "PLI", "PORTION", "POSITION", "POSITION_REGEX", "POWER", "PRECEDES",
+ "PRECEDING", "PRECISION", "PREPARE", "PRESERVE", "PREV", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURE",
+ "PUBLIC", "QUARTER", "RANGE", "RANK", "READ", "READS", "REAL", "RECURSIVE", "REF", "REFERENCES",
+ "REFERENCING", "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT", "REGR_R2", "REGR_SLOPE",
+ "REGR_SXX", "REGR_SXY", "REGR_SYY", "RELATIVE", "RELEASE", "REPEATABLE", "REPLACE", "RESET", "RESTART",
+ "RESTRICT", "RESULT", "RETURN", "RETURNED_CARDINALITY", "RETURNED_LENGTH", "RETURNED_OCTET_LENGTH",
+ "RETURNED_SQLSTATE", "RETURNS", "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROUTINE",
+ "ROUTINE_CATALOG", "ROUTINE_NAME", "ROUTINE_SCHEMA", "ROW", "ROWS", "ROW_COUNT", "ROW_NUMBER", "RUNNING",
+ "SAVEPOINT", "SCALE", "SCHEMA", "SCHEMA_NAME", "SCOPE", "SCOPE_CATALOGS", "SCOPE_NAME", "SCOPE_SCHEMA",
+ "SCROLL", "SEARCH", "SECOND", "SECTION", "SECURITY", "SEEK", "SELECT", "SELF", "SENSITIVE", "SEQUENCE",
+ "SERIALIZABLE", "SERVER", "SERVER_NAME", "SESSION", "SESSION_USER", "SET", "SETS", "SHOW", "SIMILAR",
+ "SIMPLE", "SIZE", "SKIP", "SMALLINT", "SOME", "SOURCE", "SPACE", "SPECIFIC", "SPECIFICTYPE",
+ "SPECIFIC_NAME", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", "SQL_BIGINT", "SQL_BINARY", "SQL_BIT",
+ "SQL_BLOB", "SQL_BOOLEAN", "SQL_CHAR", "SQL_CLOB", "SQL_DATE", "SQL_DECIMAL", "SQL_DOUBLE", "SQL_FLOAT",
+ "SQL_INTEGER", "SQL_INTERVAL_DAY", "SQL_INTERVAL_DAY_TO_HOUR", "SQL_INTERVAL_DAY_TO_MINUTE",
+ "SQL_INTERVAL_DAY_TO_SECOND", "SQL_INTERVAL_HOUR", "SQL_INTERVAL_HOUR_TO_MINUTE",
+ "SQL_INTERVAL_HOUR_TO_SECOND", "SQL_INTERVAL_MINUTE", "SQL_INTERVAL_MINUTE_TO_SECOND", "SQL_INTERVAL_MONTH",
+ "SQL_INTERVAL_SECOND", "SQL_INTERVAL_YEAR", "SQL_INTERVAL_YEAR_TO_MONTH", "SQL_LONGVARBINARY",
+ "SQL_LONGVARCHAR", "SQL_LONGVARNCHAR", "SQL_NCHAR", "SQL_NCLOB", "SQL_NUMERIC", "SQL_NVARCHAR", "SQL_REAL",
+ "SQL_SMALLINT", "SQL_TIME", "SQL_TIMESTAMP", "SQL_TINYINT", "SQL_TSI_DAY", "SQL_TSI_FRAC_SECOND",
+ "SQL_TSI_HOUR", "SQL_TSI_MICROSECOND", "SQL_TSI_MINUTE", "SQL_TSI_MONTH", "SQL_TSI_QUARTER",
+ "SQL_TSI_SECOND", "SQL_TSI_WEEK", "SQL_TSI_YEAR", "SQL_VARBINARY", "SQL_VARCHAR", "SQRT", "START", "STATE",
+ "STATEMENT", "STATIC", "STDDEV_POP", "STDDEV_SAMP", "STREAM", "STRUCTURE", "STYLE", "SUBCLASS_ORIGIN",
+ "SUBMULTISET", "SUBSET", "SUBSTITUTE", "SUBSTRING", "SUBSTRING_REGEX", "SUCCEEDS", "SUM", "SYMMETRIC",
+ "SYSTEM", "SYSTEM_TIME", "SYSTEM_USER", "TABLE", "TABLESAMPLE", "TABLE_NAME", "TEMPORARY", "THEN", "TIES",
+ "TIME", "TIMESTAMP", "TIMESTAMPADD", "TIMESTAMPDIFF", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TINYINT", "TO",
+ "TOP_LEVEL_COUNT", "TRAILING", "TRANSACTION", "TRANSACTIONS_ACTIVE", "TRANSACTIONS_COMMITTED",
+ "TRANSACTIONS_ROLLED_BACK", "TRANSFORM", "TRANSFORMS", "TRANSLATE", "TRANSLATE_REGEX", "TRANSLATION",
+ "TREAT", "TRIGGER", "TRIGGER_CATALOG", "TRIGGER_NAME", "TRIGGER_SCHEMA", "TRIM", "TRIM_ARRAY", "TRUE",
+ "TRUNCATE", "TYPE", "UESCAPE", "UNBOUNDED", "UNCOMMITTED", "UNDER", "UNION", "UNIQUE", "UNKNOWN", "UNNAMED",
+ "UNNEST", "UPDATE", "UPPER", "UPSERT", "USAGE", "USER", "USER_DEFINED_TYPE_CATALOG",
+ "USER_DEFINED_TYPE_CODE", "USER_DEFINED_TYPE_NAME", "USER_DEFINED_TYPE_SCHEMA", "USING", "VALUE", "VALUES",
+ "VALUE_OF", "VARBINARY", "VARCHAR", "VARYING", "VAR_POP", "VAR_SAMP", "VERSION", "VERSIONING", "VIEW",
+ "WEEK", "WHEN", "WHENEVER", "WHERE", "WIDTH_BUCKET", "WINDOW", "WITH", "WITHIN", "WITHOUT", "WORK",
+ "WRAPPER", "WRITE", "XML", "YEAR", "ZONE");
public static String replaceString(String originString, String fromString, String toString) {
return originString.replace(fromString, toString);
[06/26] kylin git commit: minor, prevent to drop job if it is stopped
Posted by li...@apache.org.
minor, prevent to drop job if it is stopped
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/8e1a7d51
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/8e1a7d51
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/8e1a7d51
Branch: refs/heads/kylin-2.1.x
Commit: 8e1a7d514519bedfbadccd3ba252ca240b56137f
Parents: c8acbc6
Author: Cheng Wang <ch...@kyligence.io>
Authored: Thu Jun 29 15:52:09 2017 +0800
Committer: 成 <ch...@kyligence.io>
Committed: Thu Jun 29 16:08:04 2017 +0800
----------------------------------------------------------------------
.../org/apache/kylin/rest/controller2/JobControllerV2.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/8e1a7d51/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
index f9db6d8..a86082c 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
@@ -282,8 +282,10 @@ public class JobControllerV2 extends BasicController {
JobInstance jobInstance = jobService.getJobInstance(jobId);
JobStatusEnum status = jobInstance.getStatus();
- if (status == JobStatusEnum.NEW || status == JobStatusEnum.PENDING || status == JobStatusEnum.RUNNING) {
- throw new BadRequestException("Cannot drop running job " + jobInstance.getName());
+ if (status == JobStatusEnum.NEW || status == JobStatusEnum.PENDING || status == JobStatusEnum.RUNNING
+ || status == JobStatusEnum.STOPPED) {
+ throw new BadRequestException(
+ "Cannot drop running job " + jobInstance.getName() + ", please discard it first.");
}
jobService.dropJob(jobInstance);
[07/26] kylin git commit: #1294 refine acl
Posted by li...@apache.org.
#1294 refine acl
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/7f790837
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/7f790837
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/7f790837
Branch: refs/heads/kylin-2.1.x
Commit: 7f79083722b634df8f4f814c6a59e0472dbcbe74
Parents: c490e6c
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 29 16:35:05 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Thu Jun 29 16:36:57 2017 +0800
----------------------------------------------------------------------
.../java/org/apache/kylin/rest/controller2/AccessControllerV2.java | 2 +-
.../src/main/java/org/apache/kylin/rest/service/AccessService.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/7f790837/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
index a61e321..1ca8652 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/AccessControllerV2.java
@@ -80,7 +80,7 @@ public class AccessControllerV2 extends BasicController {
public EnvelopeResponse listAccessEntitiesV2(@PathVariable String type, @PathVariable String uuid) {
AclEntity ae = accessService.getAclEntity(type, uuid);
Acl acl = accessService.getAcl(ae);
- return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, accessService.generateListAceResponses(acl), "");
+ return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, accessService.generateAllAceResponses(acl), "");
}
/**
http://git-wip-us.apache.org/repos/asf/kylin/blob/7f790837/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
index 3a6d723..affa508 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
@@ -322,7 +322,7 @@ public class AccessService {
}
}
- public Object generateListAceResponses(Acl acl) {
+ public Object generateAllAceResponses(Acl acl) {
List<AccessEntryResponse> result = new ArrayList<AccessEntryResponse>();
while (acl != null) {
[23/26] kylin git commit: minor, rename adhoc to pushdown in KYLIN
Posted by li...@apache.org.
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
index 8d18901..f3402ef 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
@@ -94,7 +94,7 @@ import org.apache.kylin.rest.request.PrepareSqlRequest;
import org.apache.kylin.rest.request.SQLRequest;
import org.apache.kylin.rest.response.SQLResponse;
import org.apache.kylin.rest.util.AclUtil;
-import org.apache.kylin.rest.util.AdHocUtil;
+import org.apache.kylin.rest.util.PushDownUtil;
import org.apache.kylin.rest.util.TableauInterceptor;
import org.apache.kylin.storage.hybrid.HybridInstance;
import org.slf4j.Logger;
@@ -220,7 +220,8 @@ public class QueryService extends BasicService {
return null;
}
List<Query> queries = new ArrayList<Query>();
- QueryRecord record = queryStore.getResource(getQueryKeyById(creator), QueryRecord.class, QueryRecordSerializer.getInstance());
+ QueryRecord record = queryStore.getResource(getQueryKeyById(creator), QueryRecord.class,
+ QueryRecordSerializer.getInstance());
if (record != null) {
for (Query query : record.getQueries()) {
queries.add(query);
@@ -235,7 +236,7 @@ public class QueryService extends BasicService {
final Set<Long> cuboidIds = new HashSet<Long>();
float duration = response.getDuration() / (float) 1000;
boolean storageCacheUsed = response.isStorageCacheUsed();
- boolean isAdHoc = response.isAdHoc();
+ boolean isPushDown = response.isPushDown();
if (!response.isHitExceptionCache() && null != OLAPContext.getThreadLocalContexts()) {
for (OLAPContext ctx : OLAPContext.getThreadLocalContexts()) {
@@ -276,7 +277,7 @@ public class QueryService extends BasicService {
stringBuilder.append("Is Partial Result: ").append(response.isPartial()).append(newLine);
stringBuilder.append("Hit Exception Cache: ").append(response.isHitExceptionCache()).append(newLine);
stringBuilder.append("Storage cache used: ").append(storageCacheUsed).append(newLine);
- stringBuilder.append("Is Ad-hoc Query: ").append(isAdHoc).append(newLine);
+ stringBuilder.append("Is Query Push-Down: ").append(isPushDown).append(newLine);
stringBuilder.append("Message: ").append(response.getExceptionMessage()).append(newLine);
stringBuilder.append("==========================[QUERY]===============================").append(newLine);
@@ -292,14 +293,16 @@ public class QueryService extends BasicService {
return;
}
} catch (AccessDeniedException e) {
- logger.warn("Current user {} has no READ permission on current project {}, please ask Administrator for permission granting.");
+ logger.warn(
+ "Current user {} has no READ permission on current project {}, please ask Administrator for permission granting.");
//just continue
}
String realizationsStr = sqlResponse.getCube();//CUBE[name=abc],HYBRID[name=xyz]
if (StringUtils.isEmpty(realizationsStr)) {
- throw new AccessDeniedException("Ad-hoc query requires having READ permission on project, please ask Administrator to grant you permissions");
+ throw new AccessDeniedException(
+ "Query pushdown requires having READ permission on project, please ask Administrator to grant you permissions");
}
String[] splits = StringUtils.split(realizationsStr, ",");
@@ -344,7 +347,8 @@ public class QueryService extends BasicService {
KylinConfig kylinConfig = KylinConfig.getInstanceFromEnv();
String serverMode = kylinConfig.getServerMode();
- if (!(Constant.SERVER_MODE_QUERY.equals(serverMode.toLowerCase()) || Constant.SERVER_MODE_ALL.equals(serverMode.toLowerCase()))) {
+ if (!(Constant.SERVER_MODE_QUERY.equals(serverMode.toLowerCase())
+ || Constant.SERVER_MODE_ALL.equals(serverMode.toLowerCase()))) {
throw new BadRequestException(String.format(msg.getQUERY_NOT_ALLOWED(), serverMode));
}
if (StringUtils.isBlank(sqlRequest.getProject())) {
@@ -370,7 +374,8 @@ public class QueryService extends BasicService {
long startTime = System.currentTimeMillis();
SQLResponse sqlResponse = null;
- boolean queryCacheEnabled = checkCondition(kylinConfig.isQueryCacheEnabled(), "query cache disabled in KylinConfig") && //
+ boolean queryCacheEnabled = checkCondition(kylinConfig.isQueryCacheEnabled(),
+ "query cache disabled in KylinConfig") && //
checkCondition(!BackdoorToggles.getDisableCache(), "query cache disabled in BackdoorToggles");
if (queryCacheEnabled) {
@@ -386,13 +391,22 @@ public class QueryService extends BasicService {
long scanBytesThreshold = kylinConfig.getQueryScanBytesCacheThreshold();
sqlResponse.setDuration(System.currentTimeMillis() - startTime);
logger.info("Stats of SQL response: isException: {}, duration: {}, total scan count {}", //
- String.valueOf(sqlResponse.getIsException()), String.valueOf(sqlResponse.getDuration()), String.valueOf(sqlResponse.getTotalScanCount()));
+ String.valueOf(sqlResponse.getIsException()), String.valueOf(sqlResponse.getDuration()),
+ String.valueOf(sqlResponse.getTotalScanCount()));
if (checkCondition(queryCacheEnabled, "query cache is disabled") //
&& checkCondition(!sqlResponse.getIsException(), "query has exception") //
- && checkCondition(sqlResponse.getDuration() > durationThreshold || sqlResponse.getTotalScanCount() > scanCountThreshold || sqlResponse.getTotalScanBytes() > scanBytesThreshold, //
- "query is too lightweight with duration: {} (threshold {}), scan count: {} (threshold {}), scan bytes: {} (threshold {})", sqlResponse.getDuration(), durationThreshold, sqlResponse.getTotalScanCount(), scanCountThreshold, sqlResponse.getTotalScanBytes(), scanBytesThreshold)
- && checkCondition(sqlResponse.getResults().size() < kylinConfig.getLargeQueryThreshold(), "query response is too large: {} ({})", sqlResponse.getResults().size(), kylinConfig.getLargeQueryThreshold())) {
- cacheManager.getCache(SUCCESS_QUERY_CACHE).put(new Element(sqlRequest.getCacheKey(), sqlResponse));
+ && checkCondition(
+ sqlResponse.getDuration() > durationThreshold
+ || sqlResponse.getTotalScanCount() > scanCountThreshold
+ || sqlResponse.getTotalScanBytes() > scanBytesThreshold, //
+ "query is too lightweight with duration: {} (threshold {}), scan count: {} (threshold {}), scan bytes: {} (threshold {})",
+ sqlResponse.getDuration(), durationThreshold, sqlResponse.getTotalScanCount(),
+ scanCountThreshold, sqlResponse.getTotalScanBytes(), scanBytesThreshold)
+ && checkCondition(sqlResponse.getResults().size() < kylinConfig.getLargeQueryThreshold(),
+ "query response is too large: {} ({})", sqlResponse.getResults().size(),
+ kylinConfig.getLargeQueryThreshold())) {
+ cacheManager.getCache(SUCCESS_QUERY_CACHE)
+ .put(new Element(sqlRequest.getCacheKey(), sqlResponse));
}
} else {
@@ -411,7 +425,8 @@ public class QueryService extends BasicService {
sqlResponse.setTotalScanCount(queryContext.getScannedRows());
sqlResponse.setTotalScanBytes(queryContext.getScannedBytes());
- if (queryCacheEnabled && e.getCause() != null && ExceptionUtils.getRootCause(e) instanceof ResourceLimitExceededException) {
+ if (queryCacheEnabled && e.getCause() != null
+ && ExceptionUtils.getRootCause(e) instanceof ResourceLimitExceededException) {
Cache exceptionCache = cacheManager.getCache(EXCEPTION_QUERY_CACHE);
exceptionCache.put(new Element(sqlRequest.getCacheKey(), sqlResponse));
}
@@ -459,7 +474,8 @@ public class QueryService extends BasicService {
private SQLResponse queryWithSqlMassage(SQLRequest sqlRequest) throws Exception {
String userInfo = SecurityContextHolder.getContext().getAuthentication().getName();
- final Collection<? extends GrantedAuthority> grantedAuthorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
+ final Collection<? extends GrantedAuthority> grantedAuthorities = SecurityContextHolder.getContext()
+ .getAuthentication().getAuthorities();
for (GrantedAuthority grantedAuthority : grantedAuthorities) {
userInfo += ",";
userInfo += grantedAuthority.getAuthority();
@@ -514,9 +530,12 @@ public class QueryService extends BasicService {
String schemaName = JDBCTableMeta.getString(2);
// Not every JDBC data provider offers full 10 columns, e.g., PostgreSQL has only 5
- TableMeta tblMeta = new TableMeta(catalogName == null ? Constant.FakeCatalogName : catalogName, schemaName == null ? Constant.FakeSchemaName : schemaName, JDBCTableMeta.getString(3), JDBCTableMeta.getString(4), JDBCTableMeta.getString(5), null, null, null, null, null);
+ TableMeta tblMeta = new TableMeta(catalogName == null ? Constant.FakeCatalogName : catalogName,
+ schemaName == null ? Constant.FakeSchemaName : schemaName, JDBCTableMeta.getString(3),
+ JDBCTableMeta.getString(4), JDBCTableMeta.getString(5), null, null, null, null, null);
- if (!cubedOnly || getProjectManager().isExposedTable(project, schemaName + "." + tblMeta.getTABLE_NAME())) {
+ if (!cubedOnly
+ || getProjectManager().isExposedTable(project, schemaName + "." + tblMeta.getTABLE_NAME())) {
tableMetas.add(tblMeta);
tableMap.put(tblMeta.getTABLE_SCHEM() + "#" + tblMeta.getTABLE_NAME(), tblMeta);
}
@@ -529,9 +548,18 @@ public class QueryService extends BasicService {
String schemaName = columnMeta.getString(2);
// kylin(optiq) is not strictly following JDBC specification
- ColumnMeta colmnMeta = new ColumnMeta(catalogName == null ? Constant.FakeCatalogName : catalogName, schemaName == null ? Constant.FakeSchemaName : schemaName, columnMeta.getString(3), columnMeta.getString(4), columnMeta.getInt(5), columnMeta.getString(6), columnMeta.getInt(7), getInt(columnMeta.getString(8)), columnMeta.getInt(9), columnMeta.getInt(10), columnMeta.getInt(11), columnMeta.getString(12), columnMeta.getString(13), getInt(columnMeta.getString(14)), getInt(columnMeta.getString(15)), columnMeta.getInt(16), columnMeta.getInt(17), columnMeta.getString(18), columnMeta.getString(19), columnMeta.getString(20), columnMeta.getString(21), getShort(columnMeta.getString(22)), columnMeta.getString(23));
-
- if (!cubedOnly || getProjectManager().isExposedColumn(project, schemaName + "." + colmnMeta.getTABLE_NAME(), colmnMeta.getCOLUMN_NAME())) {
+ ColumnMeta colmnMeta = new ColumnMeta(catalogName == null ? Constant.FakeCatalogName : catalogName,
+ schemaName == null ? Constant.FakeSchemaName : schemaName, columnMeta.getString(3),
+ columnMeta.getString(4), columnMeta.getInt(5), columnMeta.getString(6), columnMeta.getInt(7),
+ getInt(columnMeta.getString(8)), columnMeta.getInt(9), columnMeta.getInt(10),
+ columnMeta.getInt(11), columnMeta.getString(12), columnMeta.getString(13),
+ getInt(columnMeta.getString(14)), getInt(columnMeta.getString(15)), columnMeta.getInt(16),
+ columnMeta.getInt(17), columnMeta.getString(18), columnMeta.getString(19),
+ columnMeta.getString(20), columnMeta.getString(21), getShort(columnMeta.getString(22)),
+ columnMeta.getString(23));
+
+ if (!cubedOnly || getProjectManager().isExposedColumn(project,
+ schemaName + "." + colmnMeta.getTABLE_NAME(), colmnMeta.getCOLUMN_NAME())) {
tableMap.get(colmnMeta.getTABLE_SCHEM() + "#" + colmnMeta.getTABLE_NAME()).addColumn(colmnMeta);
}
}
@@ -551,7 +579,8 @@ public class QueryService extends BasicService {
}
@SuppressWarnings("checkstyle:methodlength")
- protected List<TableMetaWithType> getMetadataV2(CubeManager cubeMgr, String project, boolean cubedOnly) throws SQLException, IOException {
+ protected List<TableMetaWithType> getMetadataV2(CubeManager cubeMgr, String project, boolean cubedOnly)
+ throws SQLException, IOException {
//Message msg = MsgPicker.getMsg();
Connection conn = null;
@@ -578,9 +607,13 @@ public class QueryService extends BasicService {
String schemaName = JDBCTableMeta.getString(2);
// Not every JDBC data provider offers full 10 columns, e.g., PostgreSQL has only 5
- TableMetaWithType tblMeta = new TableMetaWithType(catalogName == null ? Constant.FakeCatalogName : catalogName, schemaName == null ? Constant.FakeSchemaName : schemaName, JDBCTableMeta.getString(3), JDBCTableMeta.getString(4), JDBCTableMeta.getString(5), null, null, null, null, null);
+ TableMetaWithType tblMeta = new TableMetaWithType(
+ catalogName == null ? Constant.FakeCatalogName : catalogName,
+ schemaName == null ? Constant.FakeSchemaName : schemaName, JDBCTableMeta.getString(3),
+ JDBCTableMeta.getString(4), JDBCTableMeta.getString(5), null, null, null, null, null);
- if (!cubedOnly || getProjectManager().isExposedTable(project, schemaName + "." + tblMeta.getTABLE_NAME())) {
+ if (!cubedOnly
+ || getProjectManager().isExposedTable(project, schemaName + "." + tblMeta.getTABLE_NAME())) {
tableMetas.add(tblMeta);
tableMap.put(tblMeta.getTABLE_SCHEM() + "#" + tblMeta.getTABLE_NAME(), tblMeta);
}
@@ -593,11 +626,22 @@ public class QueryService extends BasicService {
String schemaName = columnMeta.getString(2);
// kylin(optiq) is not strictly following JDBC specification
- ColumnMetaWithType colmnMeta = new ColumnMetaWithType(catalogName == null ? Constant.FakeCatalogName : catalogName, schemaName == null ? Constant.FakeSchemaName : schemaName, columnMeta.getString(3), columnMeta.getString(4), columnMeta.getInt(5), columnMeta.getString(6), columnMeta.getInt(7), getInt(columnMeta.getString(8)), columnMeta.getInt(9), columnMeta.getInt(10), columnMeta.getInt(11), columnMeta.getString(12), columnMeta.getString(13), getInt(columnMeta.getString(14)), getInt(columnMeta.getString(15)), columnMeta.getInt(16), columnMeta.getInt(17), columnMeta.getString(18), columnMeta.getString(19), columnMeta.getString(20), columnMeta.getString(21), getShort(columnMeta.getString(22)), columnMeta.getString(23));
-
- if (!cubedOnly || getProjectManager().isExposedColumn(project, schemaName + "." + colmnMeta.getTABLE_NAME(), colmnMeta.getCOLUMN_NAME())) {
+ ColumnMetaWithType colmnMeta = new ColumnMetaWithType(
+ catalogName == null ? Constant.FakeCatalogName : catalogName,
+ schemaName == null ? Constant.FakeSchemaName : schemaName, columnMeta.getString(3),
+ columnMeta.getString(4), columnMeta.getInt(5), columnMeta.getString(6), columnMeta.getInt(7),
+ getInt(columnMeta.getString(8)), columnMeta.getInt(9), columnMeta.getInt(10),
+ columnMeta.getInt(11), columnMeta.getString(12), columnMeta.getString(13),
+ getInt(columnMeta.getString(14)), getInt(columnMeta.getString(15)), columnMeta.getInt(16),
+ columnMeta.getInt(17), columnMeta.getString(18), columnMeta.getString(19),
+ columnMeta.getString(20), columnMeta.getString(21), getShort(columnMeta.getString(22)),
+ columnMeta.getString(23));
+
+ if (!cubedOnly || getProjectManager().isExposedColumn(project,
+ schemaName + "." + colmnMeta.getTABLE_NAME(), colmnMeta.getCOLUMN_NAME())) {
tableMap.get(colmnMeta.getTABLE_SCHEM() + "#" + colmnMeta.getTABLE_NAME()).addColumn(colmnMeta);
- columnMap.put(colmnMeta.getTABLE_SCHEM() + "#" + colmnMeta.getTABLE_NAME() + "#" + colmnMeta.getCOLUMN_NAME(), colmnMeta);
+ columnMap.put(colmnMeta.getTABLE_SCHEM() + "#" + colmnMeta.getTABLE_NAME() + "#"
+ + colmnMeta.getCOLUMN_NAME(), colmnMeta);
}
}
@@ -638,7 +682,8 @@ public class QueryService extends BasicService {
for (JoinTableDesc joinTableDesc : dataModelDesc.getJoinTables()) {
JoinDesc joinDesc = joinTableDesc.getJoin();
for (String pk : joinDesc.getPrimaryKey()) {
- String columnIdentity = (dataModelDesc.findTable(pk.substring(0, pk.indexOf("."))).getTableIdentity() + pk.substring(pk.indexOf("."))).replace('.', '#');
+ String columnIdentity = (dataModelDesc.findTable(pk.substring(0, pk.indexOf(".")))
+ .getTableIdentity() + pk.substring(pk.indexOf("."))).replace('.', '#');
if (columnMap.containsKey(columnIdentity)) {
columnMap.get(columnIdentity).getTYPE().add(ColumnMetaWithType.columnTypeEnum.PK);
} else {
@@ -647,7 +692,8 @@ public class QueryService extends BasicService {
}
for (String fk : joinDesc.getForeignKey()) {
- String columnIdentity = (dataModelDesc.findTable(fk.substring(0, fk.indexOf("."))).getTableIdentity() + fk.substring(fk.indexOf("."))).replace('.', '#');
+ String columnIdentity = (dataModelDesc.findTable(fk.substring(0, fk.indexOf(".")))
+ .getTableIdentity() + fk.substring(fk.indexOf("."))).replace('.', '#');
if (columnMap.containsKey(columnIdentity)) {
columnMap.get(columnIdentity).getTYPE().add(ColumnMetaWithType.columnTypeEnum.FK);
} else {
@@ -660,7 +706,8 @@ public class QueryService extends BasicService {
List<ModelDimensionDesc> dimensions = dataModelDesc.getDimensions();
for (ModelDimensionDesc dimension : dimensions) {
for (String column : dimension.getColumns()) {
- String columnIdentity = (dataModelDesc.findTable(dimension.getTable()).getTableIdentity() + "." + column).replace('.', '#');
+ String columnIdentity = (dataModelDesc.findTable(dimension.getTable()).getTableIdentity() + "."
+ + column).replace('.', '#');
if (columnMap.containsKey(columnIdentity)) {
columnMap.get(columnIdentity).getTYPE().add(ColumnMetaWithType.columnTypeEnum.DIMENSION);
} else {
@@ -672,7 +719,8 @@ public class QueryService extends BasicService {
String[] measures = dataModelDesc.getMetrics();
for (String measure : measures) {
- String columnIdentity = (dataModelDesc.findTable(measure.substring(0, measure.indexOf("."))).getTableIdentity() + measure.substring(measure.indexOf("."))).replace('.', '#');
+ String columnIdentity = (dataModelDesc.findTable(measure.substring(0, measure.indexOf(".")))
+ .getTableIdentity() + measure.substring(measure.indexOf("."))).replace('.', '#');
if (columnMap.containsKey(columnIdentity)) {
columnMap.get(columnIdentity).getTYPE().add(ColumnMetaWithType.columnTypeEnum.MEASURE);
} else {
@@ -703,7 +751,7 @@ public class QueryService extends BasicService {
Connection conn = null;
Statement stat = null;
ResultSet resultSet = null;
- Boolean isAdHoc = false;
+ Boolean isPushDown = false;
List<List<String>> results = Lists.newArrayList();
List<SelectedColumnMeta> columnMetas = Lists.newArrayList();
@@ -713,7 +761,7 @@ public class QueryService extends BasicService {
// special case for prepare query.
if (BackdoorToggles.getPrepareOnly()) {
- return getPrepareOnlySqlResponse(correctedSql, conn, isAdHoc, results, columnMetas);
+ return getPrepareOnlySqlResponse(correctedSql, conn, isPushDown, results, columnMetas);
}
stat = conn.createStatement();
@@ -725,7 +773,13 @@ public class QueryService extends BasicService {
// Fill in selected column meta
for (int i = 1; i <= columnCount; ++i) {
- columnMetas.add(new SelectedColumnMeta(metaData.isAutoIncrement(i), metaData.isCaseSensitive(i), metaData.isSearchable(i), metaData.isCurrency(i), metaData.isNullable(i), metaData.isSigned(i), metaData.getColumnDisplaySize(i), metaData.getColumnLabel(i), metaData.getColumnName(i), metaData.getSchemaName(i), metaData.getCatalogName(i), metaData.getTableName(i), metaData.getPrecision(i), metaData.getScale(i), metaData.getColumnType(i), metaData.getColumnTypeName(i), metaData.isReadOnly(i), metaData.isWritable(i), metaData.isDefinitelyWritable(i)));
+ columnMetas.add(new SelectedColumnMeta(metaData.isAutoIncrement(i), metaData.isCaseSensitive(i),
+ metaData.isSearchable(i), metaData.isCurrency(i), metaData.isNullable(i), metaData.isSigned(i),
+ metaData.getColumnDisplaySize(i), metaData.getColumnLabel(i), metaData.getColumnName(i),
+ metaData.getSchemaName(i), metaData.getCatalogName(i), metaData.getTableName(i),
+ metaData.getPrecision(i), metaData.getScale(i), metaData.getColumnType(i),
+ metaData.getColumnTypeName(i), metaData.isReadOnly(i), metaData.isWritable(i),
+ metaData.isDefinitelyWritable(i)));
}
// fill in results
@@ -738,17 +792,17 @@ public class QueryService extends BasicService {
results.add(oneRow);
}
} catch (SQLException sqlException) {
- isAdHoc = AdHocUtil.doAdHocQuery(sqlRequest.getProject(), correctedSql, results, columnMetas, sqlException);
+ isPushDown = PushDownUtil.doPushDownQuery(sqlRequest.getProject(), correctedSql, results, columnMetas,
+ sqlException);
} finally {
close(resultSet, stat, conn);
}
- return getSqlResponse(isAdHoc, results, columnMetas);
+ return getSqlResponse(isPushDown, results, columnMetas);
}
- private SQLResponse getPrepareOnlySqlResponse(String correctedSql, Connection conn,
- Boolean isAdHoc, List<List<String>> results, List<SelectedColumnMeta> columnMetas)
- throws SQLException {
+ private SQLResponse getPrepareOnlySqlResponse(String correctedSql, Connection conn, Boolean isPushDown,
+ List<List<String>> results, List<SelectedColumnMeta> columnMetas) throws SQLException {
CalcitePrepareImpl.KYLIN_ONLY_PREPARE.set(true);
@@ -772,7 +826,12 @@ public class QueryService extends BasicService {
String columnName = field.getKey();
BasicSqlType basicSqlType = (BasicSqlType) field.getValue();
- columnMetas.add(new SelectedColumnMeta(false, config.caseSensitive(), false, false, basicSqlType.isNullable() ? 1 : 0, true, basicSqlType.getPrecision(), columnName, columnName, null, null, null, basicSqlType.getPrecision(), basicSqlType.getScale() < 0 ? 0 : basicSqlType.getScale(), basicSqlType.getSqlTypeName().getJdbcOrdinal(), basicSqlType.getSqlTypeName().getName(), true, false, false));
+ columnMetas.add(new SelectedColumnMeta(false, config.caseSensitive(), false, false,
+ basicSqlType.isNullable() ? 1 : 0, true, basicSqlType.getPrecision(), columnName,
+ columnName, null, null, null, basicSqlType.getPrecision(),
+ basicSqlType.getScale() < 0 ? 0 : basicSqlType.getScale(),
+ basicSqlType.getSqlTypeName().getJdbcOrdinal(), basicSqlType.getSqlTypeName().getName(),
+ true, false, false));
}
} else {
@@ -782,10 +841,11 @@ public class QueryService extends BasicService {
CalcitePrepareImpl.KYLIN_ONLY_PREPARE.set(false);
}
- return getSqlResponse(isAdHoc, results, columnMetas);
+ return getSqlResponse(isPushDown, results, columnMetas);
}
- private SQLResponse getSqlResponse(Boolean isAdHoc, List<List<String>> results, List<SelectedColumnMeta> columnMetas) {
+ private SQLResponse getSqlResponse(Boolean isPushDown, List<List<String>> results,
+ List<SelectedColumnMeta> columnMetas) {
boolean isPartialResult = false;
StringBuilder cubeSb = new StringBuilder();
@@ -804,7 +864,8 @@ public class QueryService extends BasicService {
}
logger.info(logSb.toString());
- SQLResponse response = new SQLResponse(columnMetas, results, cubeSb.toString(), 0, false, null, isPartialResult, isAdHoc);
+ SQLResponse response = new SQLResponse(columnMetas, results, cubeSb.toString(), 0, false, null, isPartialResult,
+ isPushDown);
response.setTotalScanCount(QueryContext.current().getScannedRows());
response.setTotalScanBytes(QueryContext.current().getScannedBytes());
return response;
@@ -815,7 +876,8 @@ public class QueryService extends BasicService {
* @param param
* @throws SQLException
*/
- private void setParam(PreparedStatement preparedState, int index, PrepareSqlRequest.StateParam param) throws SQLException {
+ private void setParam(PreparedStatement preparedState, int index, PrepareSqlRequest.StateParam param)
+ throws SQLException {
boolean isNull = (null == param.getValue());
Class<?> clazz;
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java b/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
deleted file mode 100644
index 0eff508..0000000
--- a/server-base/src/main/java/org/apache/kylin/rest/util/AdHocUtil.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.kylin.rest.util;
-
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.commons.lang3.tuple.Triple;
-import org.apache.kylin.common.KylinConfig;
-import org.apache.kylin.common.util.ClassUtil;
-import org.apache.kylin.metadata.MetadataManager;
-import org.apache.kylin.metadata.model.ComputedColumnDesc;
-import org.apache.kylin.metadata.model.DataModelDesc;
-import org.apache.kylin.metadata.model.tool.CalciteParser;
-import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
-import org.apache.kylin.query.routing.NoRealizationFoundException;
-import org.apache.kylin.source.adhocquery.IAdHocConverter;
-import org.apache.kylin.source.adhocquery.IAdHocRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
-public class AdHocUtil {
- private static final Logger logger = LoggerFactory.getLogger(AdHocUtil.class);
-
- public static boolean doAdHocQuery(String project, String sql, List<List<String>> results,
- List<SelectedColumnMeta> columnMetas, SQLException sqlException) throws Exception {
-
- boolean isExpectedCause = (ExceptionUtils.getRootCause(sqlException).getClass()
- .equals(NoRealizationFoundException.class));
- KylinConfig kylinConfig = KylinConfig.getInstanceFromEnv();
-
- if (isExpectedCause && kylinConfig.isAdhocEnabled()) {
-
- logger.info("Query failed to utilize pre-calculation, routing to other engines", sqlException);
- IAdHocRunner runner = (IAdHocRunner) ClassUtil.newInstance(kylinConfig.getAdHocRunnerClassName());
- IAdHocConverter converter = (IAdHocConverter) ClassUtil
- .newInstance(kylinConfig.getAdHocConverterClassName());
-
- runner.init(kylinConfig);
-
- logger.debug("Ad-hoc query runner {}", runner);
-
- String expandCC = restoreComputedColumnToExpr(sql, project);
- if (!StringUtils.equals(expandCC, sql)) {
- logger.info("computed column in sql is expanded to: " + expandCC);
- }
- String adhocSql = converter.convert(expandCC);
- if (!adhocSql.equals(expandCC)) {
- logger.info("the query is converted to {} according to kylin.query.ad-hoc.converter-class-name",
- adhocSql);
- }
-
- runner.executeQuery(adhocSql, results, columnMetas);
-
- return true;
- } else {
- throw sqlException;
- }
- }
-
- private final static Pattern identifierInSqlPattern = Pattern.compile(
- //find pattern like "table"."column" or "column"
- "((?<![\\p{L}_0-9\\.\\\"])(\\\"[\\p{L}_0-9]+\\\"\\.)?(\\\"[\\p{L}_0-9]+\\\")(?![\\p{L}_0-9\\.\\\"]))" + "|"
- //find pattern like table.column or column
- + "((?<![\\p{L}_0-9\\.\\\"])([\\p{L}_0-9]+\\.)?([\\p{L}_0-9]+)(?![\\p{L}_0-9\\.\\\"]))");
-
- private final static Pattern identifierInExprPattern = Pattern.compile(
- // a.b.c
- "((?<![\\p{L}_0-9\\.\\\"])([\\p{L}_0-9]+\\.)([\\p{L}_0-9]+\\.)([\\p{L}_0-9]+)(?![\\p{L}_0-9\\.\\\"]))");
-
- private final static Pattern endWithAsPattern = Pattern.compile("\\s+as\\s+$", Pattern.CASE_INSENSITIVE);
-
- public static String restoreComputedColumnToExpr(String beforeSql, String project) {
- final MetadataManager metadataManager = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
- List<DataModelDesc> dataModelDescs = metadataManager.getModels(project);
-
- String afterSql = beforeSql;
- for (DataModelDesc dataModelDesc : dataModelDescs) {
- for (ComputedColumnDesc computedColumnDesc : dataModelDesc.getComputedColumnDescs()) {
- afterSql = restoreComputedColumnToExpr(afterSql, computedColumnDesc);
- }
- }
-
- return afterSql;
- }
-
- static String restoreComputedColumnToExpr(String sql, ComputedColumnDesc computedColumnDesc) {
-
- String ccName = computedColumnDesc.getColumnName();
- List<Triple<Integer, Integer, String>> replacements = Lists.newArrayList();
- Matcher matcher = identifierInSqlPattern.matcher(sql);
-
- while (matcher.find()) {
- if (matcher.group(1) != null) { //with quote case: "TABLE"."COLUMN"
-
- String quotedColumnName = matcher.group(3);
- Preconditions.checkNotNull(quotedColumnName);
- String columnName = StringUtils.strip(quotedColumnName, "\"");
- if (!columnName.equalsIgnoreCase(ccName)) {
- continue;
- }
-
- if (matcher.group(2) != null) { // table name exist
- String quotedTableAlias = StringUtils.strip(matcher.group(2), ".");
- String tableAlias = StringUtils.strip(quotedTableAlias, "\"");
- replacements.add(Triple.of(matcher.start(1), matcher.end(1),
- replaceIdentifierInExpr(computedColumnDesc.getExpression(), tableAlias, true)));
- } else { //only column
- if (endWithAsPattern.matcher(sql.substring(0, matcher.start(1))).find()) {
- //select DEAL_AMOUNT as "deal_amount" case
- continue;
- }
- replacements.add(Triple.of(matcher.start(1), matcher.end(1),
- replaceIdentifierInExpr(computedColumnDesc.getExpression(), null, true)));
- }
- } else if (matcher.group(4) != null) { //without quote case: table.column or simply column
- String columnName = matcher.group(6);
- Preconditions.checkNotNull(columnName);
- if (!columnName.equalsIgnoreCase(ccName)) {
- continue;
- }
-
- if (matcher.group(5) != null) { //table name exist
- String tableAlias = StringUtils.strip(matcher.group(5), ".");
- replacements.add(Triple.of(matcher.start(4), matcher.end(4),
- replaceIdentifierInExpr(computedColumnDesc.getExpression(), tableAlias, false)));
-
- } else { //only column
- if (endWithAsPattern.matcher(sql.substring(0, matcher.start(4))).find()) {
- //select DEAL_AMOUNT as deal_amount case
- continue;
- }
- replacements.add(Triple.of(matcher.start(4), matcher.end(4),
- replaceIdentifierInExpr(computedColumnDesc.getExpression(), null, false)));
- }
- }
- }
-
- Collections.reverse(replacements);
- for (Triple<Integer, Integer, String> triple : replacements) {
- sql = sql.substring(0, triple.getLeft()) + "(" + triple.getRight() + ")"
- + sql.substring(triple.getMiddle());
- }
- return sql;
- }
-
- static String replaceIdentifierInExpr(String expr, String tableAlias, boolean quoted) {
- if (tableAlias == null) {
- return expr;
- }
-
- return CalciteParser.insertAliasInExpr(expr, tableAlias);
- }
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/server-base/src/main/java/org/apache/kylin/rest/util/PushDownUtil.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/util/PushDownUtil.java b/server-base/src/main/java/org/apache/kylin/rest/util/PushDownUtil.java
new file mode 100644
index 0000000..5d7f47a
--- /dev/null
+++ b/server-base/src/main/java/org/apache/kylin/rest/util/PushDownUtil.java
@@ -0,0 +1,177 @@
+/*
+ * 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.kylin.rest.util;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.commons.lang3.tuple.Triple;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.util.ClassUtil;
+import org.apache.kylin.metadata.MetadataManager;
+import org.apache.kylin.metadata.model.ComputedColumnDesc;
+import org.apache.kylin.metadata.model.DataModelDesc;
+import org.apache.kylin.metadata.model.tool.CalciteParser;
+import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
+import org.apache.kylin.query.routing.NoRealizationFoundException;
+import org.apache.kylin.source.adhocquery.IPushDownConverter;
+import org.apache.kylin.source.adhocquery.IPushDownRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+public class PushDownUtil {
+ private static final Logger logger = LoggerFactory.getLogger(PushDownUtil.class);
+
+ public static boolean doPushDownQuery(String project, String sql, List<List<String>> results,
+ List<SelectedColumnMeta> columnMetas, SQLException sqlException) throws Exception {
+
+ boolean isExpectedCause = (ExceptionUtils.getRootCause(sqlException).getClass()
+ .equals(NoRealizationFoundException.class));
+ KylinConfig kylinConfig = KylinConfig.getInstanceFromEnv();
+
+ if (isExpectedCause && kylinConfig.isPushDownEnabled()) {
+
+ logger.info("Query failed to utilize pre-calculation, routing to other engines", sqlException);
+ IPushDownRunner runner = (IPushDownRunner) ClassUtil.newInstance(kylinConfig.getPushDownRunnerClassName());
+ IPushDownConverter converter = (IPushDownConverter) ClassUtil
+ .newInstance(kylinConfig.getPushDownConverterClassName());
+
+ runner.init(kylinConfig);
+
+ logger.debug("Query pushdown runner {}", runner);
+
+ String expandCC = restoreComputedColumnToExpr(sql, project);
+ if (!StringUtils.equals(expandCC, sql)) {
+ logger.info("computed column in sql is expanded to: " + expandCC);
+ }
+ String adhocSql = converter.convert(expandCC);
+ if (!adhocSql.equals(expandCC)) {
+ logger.info("the query is converted to {} according to kylin.query.pushdown.converter-class-name",
+ adhocSql);
+ }
+
+ runner.executeQuery(adhocSql, results, columnMetas);
+
+ return true;
+ } else {
+ throw sqlException;
+ }
+ }
+
+ private final static Pattern identifierInSqlPattern = Pattern.compile(
+ //find pattern like "table"."column" or "column"
+ "((?<![\\p{L}_0-9\\.\\\"])(\\\"[\\p{L}_0-9]+\\\"\\.)?(\\\"[\\p{L}_0-9]+\\\")(?![\\p{L}_0-9\\.\\\"]))" + "|"
+ //find pattern like table.column or column
+ + "((?<![\\p{L}_0-9\\.\\\"])([\\p{L}_0-9]+\\.)?([\\p{L}_0-9]+)(?![\\p{L}_0-9\\.\\\"]))");
+
+ private final static Pattern identifierInExprPattern = Pattern.compile(
+ // a.b.c
+ "((?<![\\p{L}_0-9\\.\\\"])([\\p{L}_0-9]+\\.)([\\p{L}_0-9]+\\.)([\\p{L}_0-9]+)(?![\\p{L}_0-9\\.\\\"]))");
+
+ private final static Pattern endWithAsPattern = Pattern.compile("\\s+as\\s+$", Pattern.CASE_INSENSITIVE);
+
+ public static String restoreComputedColumnToExpr(String beforeSql, String project) {
+ final MetadataManager metadataManager = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
+ List<DataModelDesc> dataModelDescs = metadataManager.getModels(project);
+
+ String afterSql = beforeSql;
+ for (DataModelDesc dataModelDesc : dataModelDescs) {
+ for (ComputedColumnDesc computedColumnDesc : dataModelDesc.getComputedColumnDescs()) {
+ afterSql = restoreComputedColumnToExpr(afterSql, computedColumnDesc);
+ }
+ }
+ return afterSql;
+ }
+
+ static String restoreComputedColumnToExpr(String sql, ComputedColumnDesc computedColumnDesc) {
+
+ String ccName = computedColumnDesc.getColumnName();
+ List<Triple<Integer, Integer, String>> replacements = Lists.newArrayList();
+ Matcher matcher = identifierInSqlPattern.matcher(sql);
+
+ while (matcher.find()) {
+ if (matcher.group(1) != null) { //with quote case: "TABLE"."COLUMN"
+
+ String quotedColumnName = matcher.group(3);
+ Preconditions.checkNotNull(quotedColumnName);
+ String columnName = StringUtils.strip(quotedColumnName, "\"");
+ if (!columnName.equalsIgnoreCase(ccName)) {
+ continue;
+ }
+
+ if (matcher.group(2) != null) { // table name exist
+ String quotedTableAlias = StringUtils.strip(matcher.group(2), ".");
+ String tableAlias = StringUtils.strip(quotedTableAlias, "\"");
+ replacements.add(Triple.of(matcher.start(1), matcher.end(1),
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), tableAlias, true)));
+ } else { //only column
+ if (endWithAsPattern.matcher(sql.substring(0, matcher.start(1))).find()) {
+ //select DEAL_AMOUNT as "deal_amount" case
+ continue;
+ }
+ replacements.add(Triple.of(matcher.start(1), matcher.end(1),
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), null, true)));
+ }
+ } else if (matcher.group(4) != null) { //without quote case: table.column or simply column
+ String columnName = matcher.group(6);
+ Preconditions.checkNotNull(columnName);
+ if (!columnName.equalsIgnoreCase(ccName)) {
+ continue;
+ }
+
+ if (matcher.group(5) != null) { //table name exist
+ String tableAlias = StringUtils.strip(matcher.group(5), ".");
+ replacements.add(Triple.of(matcher.start(4), matcher.end(4),
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), tableAlias, false)));
+
+ } else { //only column
+ if (endWithAsPattern.matcher(sql.substring(0, matcher.start(4))).find()) {
+ //select DEAL_AMOUNT as deal_amount case
+ continue;
+ }
+ replacements.add(Triple.of(matcher.start(4), matcher.end(4),
+ replaceIdentifierInExpr(computedColumnDesc.getExpression(), null, false)));
+ }
+ }
+ }
+
+ Collections.reverse(replacements);
+ for (Triple<Integer, Integer, String> triple : replacements) {
+ sql = sql.substring(0, triple.getLeft()) + "(" + triple.getRight() + ")"
+ + sql.substring(triple.getMiddle());
+ }
+ return sql;
+ }
+
+ static String replaceIdentifierInExpr(String expr, String tableAlias, boolean quoted) {
+ if (tableAlias == null) {
+ return expr;
+ }
+
+ return CalciteParser.insertAliasInExpr(expr, tableAlias);
+ }
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
----------------------------------------------------------------------
diff --git a/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java b/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
deleted file mode 100644
index 05b135a..0000000
--- a/server-base/src/test/java/org/apache/kylin/rest/util/AdHocUtilTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.kylin.rest.util;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.apache.kylin.metadata.model.ComputedColumnDesc;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class AdHocUtilTest {
-
- @Test
- public void testReplaceIdentifierInExpr() {
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("x * y", null, false);
- Assert.assertEquals("x * y", ret);
- }
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("x_3 * y_3", "b_2", false);
- Assert.assertEquals("b_2.x_3 * b_2.y_3", ret);
- }
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("substr(x,1,3)>y", "c", true);
- Assert.assertEquals("substr(c.x,1,3)>c.y", ret);
- }
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", "c", true);
- Assert.assertEquals("strcmp(substr(c.x,1,3),c.y)", ret);
- }
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", null, true);
- Assert.assertEquals("strcmp(substr(x,1,3),y)", ret);
- }
- {
- String ret = AdHocUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", null, false);
- Assert.assertEquals("strcmp(substr(x,1,3),y)", ret);
- }
- }
-
- @Test
- public void testRestoreComputedColumnToExpr() {
-
- ComputedColumnDesc computedColumnDesc = mock(ComputedColumnDesc.class);
- when(computedColumnDesc.getColumnName()).thenReturn("DEAL_AMOUNT");
- when(computedColumnDesc.getExpression()).thenReturn("price * number");
-
- {
- String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT", computedColumnDesc);
- Assert.assertEquals("select (price * number) from DB.TABLE group by date order by (price * number)", ret);
- }
- {
- String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select DEAL_AMOUNT as DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT",
- computedColumnDesc);
- Assert.assertEquals(
- "select (price * number) as DEAL_AMOUNT from DB.TABLE group by date order by (price * number)",
- ret);
- }
- {
- String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select \"DEAL_AMOUNT\" AS deal_amount from DB.TABLE group by date order by DEAL_AMOUNT",
- computedColumnDesc);
- Assert.assertEquals(
- "select (price * number) AS deal_amount from DB.TABLE group by date order by (price * number)",
- ret);
- }
- {
- String ret = AdHocUtil.restoreComputedColumnToExpr(
- "select x.DEAL_AMOUNT AS deal_amount from DB.TABLE x group by date order by x.DEAL_AMOUNT",
- computedColumnDesc);
- Assert.assertEquals(
- "select (x.price * x.number) AS deal_amount from DB.TABLE x group by date order by (x.price * x.number)",
- ret);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/7002dd86/server-base/src/test/java/org/apache/kylin/rest/util/PushDownUtilTest.java
----------------------------------------------------------------------
diff --git a/server-base/src/test/java/org/apache/kylin/rest/util/PushDownUtilTest.java b/server-base/src/test/java/org/apache/kylin/rest/util/PushDownUtilTest.java
new file mode 100644
index 0000000..5302a70
--- /dev/null
+++ b/server-base/src/test/java/org/apache/kylin/rest/util/PushDownUtilTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.kylin.rest.util;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.kylin.metadata.model.ComputedColumnDesc;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PushDownUtilTest {
+
+ @Test
+ public void testReplaceIdentifierInExpr() {
+ {
+ String ret = PushDownUtil.replaceIdentifierInExpr("x * y", null, false);
+ Assert.assertEquals("x * y", ret);
+ }
+ {
+ String ret = PushDownUtil.replaceIdentifierInExpr("x_3 * y_3", "b_2", false);
+ Assert.assertEquals("b_2.x_3 * b_2.y_3", ret);
+ }
+ {
+ String ret = PushDownUtil.replaceIdentifierInExpr("substr(x,1,3)>y", "c", true);
+ Assert.assertEquals("substr(c.x,1,3)>c.y", ret);
+ }
+ {
+ String ret = PushDownUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", "c", true);
+ Assert.assertEquals("strcmp(substr(c.x,1,3),c.y)", ret);
+ }
+ {
+ String ret = PushDownUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", null, true);
+ Assert.assertEquals("strcmp(substr(x,1,3),y)", ret);
+ }
+ {
+ String ret = PushDownUtil.replaceIdentifierInExpr("strcmp(substr(x,1,3),y)", null, false);
+ Assert.assertEquals("strcmp(substr(x,1,3),y)", ret);
+ }
+ }
+
+ @Test
+ public void testRestoreComputedColumnToExpr() {
+
+ ComputedColumnDesc computedColumnDesc = mock(ComputedColumnDesc.class);
+ when(computedColumnDesc.getColumnName()).thenReturn("DEAL_AMOUNT");
+ when(computedColumnDesc.getExpression()).thenReturn("price * number");
+
+ {
+ String ret = PushDownUtil.restoreComputedColumnToExpr(
+ "select DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT", computedColumnDesc);
+ Assert.assertEquals("select (price * number) from DB.TABLE group by date order by (price * number)", ret);
+ }
+ {
+ String ret = PushDownUtil.restoreComputedColumnToExpr(
+ "select DEAL_AMOUNT as DEAL_AMOUNT from DB.TABLE group by date order by DEAL_AMOUNT",
+ computedColumnDesc);
+ Assert.assertEquals(
+ "select (price * number) as DEAL_AMOUNT from DB.TABLE group by date order by (price * number)",
+ ret);
+ }
+ {
+ String ret = PushDownUtil.restoreComputedColumnToExpr(
+ "select \"DEAL_AMOUNT\" AS deal_amount from DB.TABLE group by date order by DEAL_AMOUNT",
+ computedColumnDesc);
+ Assert.assertEquals(
+ "select (price * number) AS deal_amount from DB.TABLE group by date order by (price * number)",
+ ret);
+ }
+ {
+ String ret = PushDownUtil.restoreComputedColumnToExpr(
+ "select x.DEAL_AMOUNT AS deal_amount from DB.TABLE x group by date order by x.DEAL_AMOUNT",
+ computedColumnDesc);
+ Assert.assertEquals(
+ "select (x.price * x.number) AS deal_amount from DB.TABLE x group by date order by (x.price * x.number)",
+ ret);
+ }
+ }
+}
[21/26] kylin git commit: minor, roll back validate join key
Posted by li...@apache.org.
minor, roll back validate join key
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/3ae8ca7c
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/3ae8ca7c
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/3ae8ca7c
Branch: refs/heads/kylin-2.1.x
Commit: 3ae8ca7cd3796583787e0657edec31b8bdb30ce1
Parents: dc232d1
Author: Cheng Wang <ch...@kyligence.io>
Authored: Fri Jun 30 20:26:31 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 30 20:29:11 2017 +0800
----------------------------------------------------------------------
.../kylin/metadata/model/DataModelDesc.java | 31 --------------------
1 file changed, 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/3ae8ca7c/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
index abee71b..bc35e2a 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
@@ -617,38 +617,7 @@ public class DataModelDesc extends RootPersistentEntity {
+ fkCols[i].getDatatype());
}
}
-
- if (!isSpecialTestModel()) {
- for (TblColRef t : fkCols) {
- if (!isJoinKeyDimension(t.getIdentity())) {
- throw new IllegalStateException(
- "Foreigner key: " + t.getIdentity() + " should be a dimension.");
- }
- }
-
- for (TblColRef t : pkCols) {
- if (!isJoinKeyDimension(t.getIdentity())) {
- throw new IllegalStateException("Primary key: " + t.getIdentity() + " should be a dimension.");
- }
- }
- }
- }
- }
-
- private boolean isJoinKeyDimension(String key) {
- for (ModelDimensionDesc d : dimensions) {
- for (String col : d.getColumns()) {
- if (key.equals(d.getTable() + '.' + col))
- return true;
- }
}
- return false;
- }
-
- private boolean isSpecialTestModel() {
- if (config.isDevEnv() && (name.startsWith("test_kylin_") || name.startsWith("test_streaming")))
- return true;
- return false;
}
private void initJoinsTree() {
[26/26] kylin git commit: minor, rename adhoc to pushdown
Posted by li...@apache.org.
minor, rename adhoc to pushdown
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/82b578a5
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/82b578a5
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/82b578a5
Branch: refs/heads/kylin-2.1.x
Commit: 82b578a561de76e93dcd0b56473bbd229e1292b9
Parents: 4f4382d
Author: Hongbin Ma <ma...@apache.org>
Authored: Sat Jul 1 12:25:21 2017 +0800
Committer: Roger Shi <ro...@gmail.com>
Committed: Sat Jul 1 12:30:52 2017 +0800
----------------------------------------------------------------------
build/smoke-test/sql/sql1.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/82b578a5/build/smoke-test/sql/sql1.json
----------------------------------------------------------------------
diff --git a/build/smoke-test/sql/sql1.json b/build/smoke-test/sql/sql1.json
index 7b90d0f..a8d01b0 100644
--- a/build/smoke-test/sql/sql1.json
+++ b/build/smoke-test/sql/sql1.json
@@ -3,7 +3,7 @@
"partial": false,
"affectedRowCount": 0,
"isException": false,
- "adHoc": false,
+ "pushDown": false,
"results": [
[
"10000"