KYLIN-2515 code review

Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/f6cdd629
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/f6cdd629
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/f6cdd629

Branch: refs/heads/master
Commit: f6cdd629817d18b60d6885753eb9681cfa4b57f2
Parents: 216ae03
Author: Yang Li <liy...@apache.org>
Authored: Sun Jun 4 16:31:31 2017 +0800
Committer: nichunen <zjsy...@sjtu.org>
Committed: Sun Jun 4 18:01:03 2017 +0800

----------------------------------------------------------------------
 build/conf/kylin.properties                     |   8 +-
 .../apache/kylin/common/KylinConfigBase.java    |  10 +-
 .../metadata/querymeta/ColumnMetaWithType.java  |   1 +
 .../metadata/querymeta/SelectedColumnMeta.java  |   1 +
 .../metadata/querymeta/TableMetaWithType.java   |   1 +
 .../source/adhocquery/HiveAdhocConverter.java   | 181 +++++++++++++++++++
 .../source/adhocquery/IAdHocConverter.java      |  25 +++
 .../kylin/source/adhocquery/IAdHocRunner.java   |  39 ++++
 .../adhocquery/HiveAdhocConverterTest.java      |  63 +++++++
 .../kylin/storage/adhoc/AdHocRunnerBase.java    |  48 -----
 .../kylin/storage/adhoc/HiveAdhocConverter.java | 180 ------------------
 .../kylin/storage/adhoc/IAdhocConverter.java    |  25 ---
 .../storage/adhoc/HiveAdhocConverterTest.java   |  62 -------
 .../test_case_data/sandbox/kylin.properties     |   8 +-
 .../kylin/rest/adhoc/AdHocRunnerJdbcImpl.java   |  32 ++--
 .../kylin/rest/adhoc/JdbcConnectionFactory.java |   5 +-
 .../kylin/rest/controller/QueryController.java  |   5 +-
 .../org/apache/kylin/rest/util/AdHocUtil.java   |  53 ++----
 18 files changed, 358 insertions(+), 389 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/build/conf/kylin.properties
----------------------------------------------------------------------
diff --git a/build/conf/kylin.properties b/build/conf/kylin.properties
index 8949a42..44a38d2 100644
--- a/build/conf/kylin.properties
+++ b/build/conf/kylin.properties
@@ -237,13 +237,13 @@ 
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 ###
-#kylin.query.ad-hoc.runner.class-name=org.apache.kylin.rest.adhoc.AdHocRunnerJdbcImpl
+#kylin.query.ad-hoc.runner-class-name=org.apache.kylin.rest.adhoc.AdHocRunnerJdbcImpl
 
 #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.ad-hoc.pool.max-total=8
-#kylin.query.ad-hoc.pool.max-idle=8
-#kylin.query.ad-hoc.pool.min-idle=0
+#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

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/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 f465949..c83c546 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
@@ -986,11 +986,11 @@ abstract public class KylinConfigBase implements 
Serializable {
     }
 
     public String getAdHocRunnerClassName() {
-        return getOptional("kylin.query.ad-hoc.runner.class-name", "");
+        return getOptional("kylin.query.ad-hoc.runner-class-name", "");
     }
 
     public String getAdHocConverterClassName() {
-        return getOptional("kylin.query.ad-hoc.converter.class-name", 
"org.apache.kylin.storage.adhoc.HiveAdhocConverter");
+        return getOptional("kylin.query.ad-hoc.converter-class-name", 
"org.apache.kylin.source.adhocquery.HiveAdhocConverter");
     }
 
     public String getJdbcUrl() {
@@ -1010,15 +1010,15 @@ abstract public class KylinConfigBase implements 
Serializable {
     }
 
     public int getPoolMaxTotal() {
-        return 
Integer.parseInt(this.getOptional("kylin.query.ad-hoc.pool.max-total", "8"));
+        return 
Integer.parseInt(this.getOptional("kylin.query.ad-hoc.jdbc.pool-max-total", 
"8"));
     }
 
     public int getPoolMaxIdle() {
-        return 
Integer.parseInt(this.getOptional("kylin.query.ad-hoc.pool.max-idle", "8"));
+        return 
Integer.parseInt(this.getOptional("kylin.query.ad-hoc.jdbc.pool-max-idle", 
"8"));
     }
 
     public int getPoolMinIdle() {
-        return 
Integer.parseInt(this.getOptional("kylin.query.ad-hoc.pool.min-idle", "0"));
+        return 
Integer.parseInt(this.getOptional("kylin.query.ad-hoc.jdbc.pool-min-idle", 
"0"));
     }
 
     // 
============================================================================

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/ColumnMetaWithType.java
----------------------------------------------------------------------
diff --git 
a/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/ColumnMetaWithType.java
 
b/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/ColumnMetaWithType.java
index e3cb86b..101ebd5 100644
--- 
a/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/ColumnMetaWithType.java
+++ 
b/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/ColumnMetaWithType.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
 /**
  * Created by luwei on 17-4-26.
  */
+@SuppressWarnings("serial")
 public class ColumnMetaWithType extends ColumnMeta {
     public static enum columnTypeEnum implements Serializable {
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/SelectedColumnMeta.java
----------------------------------------------------------------------
diff --git 
a/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/SelectedColumnMeta.java
 
b/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/SelectedColumnMeta.java
index 9ba0da2..1cbe8ab 100644
--- 
a/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/SelectedColumnMeta.java
+++ 
b/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/SelectedColumnMeta.java
@@ -22,6 +22,7 @@ import java.io.Serializable;
 
 /**
  */
+@SuppressWarnings("serial")
 public class SelectedColumnMeta implements Serializable {
     public SelectedColumnMeta(boolean isAutoIncrement, boolean 
isCaseSensitive, boolean isSearchable, boolean isCurrency, int isNullalbe, 
boolean isSigned, int displaySize, String label, String name, String 
schemaName, String catelogName, String tableName, int precision, int scale, int 
columnType, String columnTypeName, boolean isReadOnly, boolean isWritable, 
boolean isDefinitelyWritable) {
         super();

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/TableMetaWithType.java
----------------------------------------------------------------------
diff --git 
a/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/TableMetaWithType.java
 
b/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/TableMetaWithType.java
index 2ff21e4..e16aba6 100644
--- 
a/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/TableMetaWithType.java
+++ 
b/core-metadata/src/main/java/org/apache/kylin/metadata/querymeta/TableMetaWithType.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
 /**
  * Created by luwei on 17-4-26.
  */
+@SuppressWarnings("serial")
 public class TableMetaWithType extends TableMeta {
     public static enum tableTypeEnum implements Serializable {
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/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
new file mode 100644
index 0000000..97d77bf
--- /dev/null
+++ 
b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
@@ -0,0 +1,181 @@
+/*
+ * 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;
+
+//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("\\s+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 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);
+
+    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) + 1;
+            int originEnd = endIdx + 1;
+
+            replacedString = replaceString(replacedString, 
originString.substring(originStart, originEnd), functionStr + "(" + 
extractInner + ")");
+        }
+
+        return replacedString;
+    }
+
+    public static String castRepalce(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 subqueryRepalce(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;
+
+            replacedString = replaceString(replacedString, 
originString.substring(startIdx, endIdx), originString.substring(startIdx, 
endIdx) + " as alias");
+        }
+
+        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 = castRepalce(convertedSql);
+
+        // Step4.Replace sub query
+        convertedSql = subqueryRepalce(convertedSql);
+
+        // Step5.Replace char_length with length
+        convertedSql = replaceString(convertedSql, "char_length", "length");
+
+        // Step6.Replace "||" with concat
+        convertedSql = concatReplace(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/f6cdd629/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
new file mode 100644
index 0000000..c4b87f8
--- /dev/null
+++ 
b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocConverter.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 adhoc query engine
+ */
+public interface IAdHocConverter {
+    String convert(String originSql);
+}

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/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
new file mode 100644
index 0000000..369325c
--- /dev/null
+++ 
b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/IAdHocRunner.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 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/f6cdd629/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
new file mode 100644
index 0000000..85a6d61
--- /dev/null
+++ 
b/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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 testSringReplace() {
+        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(replacedString, "select count(*) as cnt from 
test_kylin_fact where length(lstg_format_name) < 10");
+    }
+
+    @Test
+    public void testExtractReplace() {
+        String originString = "ignore EXTRACT(YEAR FROM KYLIN_CAL_DT.CAL_DT) 
ignore";
+        String replacedString = 
HiveAdhocConverter.extractReplace(originString);
+        assertEquals(replacedString, "ignore YEAR(KYLIN_CAL_DT.CAL_DT) 
ignore");
+    }
+
+    @Test
+    public void testCastReplace() {
+        String originString = "ignore EXTRACT(YEAR FROM 
CAST(KYLIN_CAL_DT.CAL_DT AS INTEGER)) ignore";
+        String replacedString = HiveAdhocConverter.castRepalce(originString);
+        assertEquals(replacedString, "ignore EXTRACT(YEAR FROM 
CAST(KYLIN_CAL_DT.CAL_DT AS int)) ignore");
+    }
+
+    @Test
+    public void testSubqueryReplace() {
+        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.subqueryRepalce(originString);
+        assertEquals(replacedString, "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");
+    }
+
+    @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(replacedString, "select count(*) as cnt from 
test_kylin_fact where concat(lstg_format_name,'a')='ABINa'");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/core-storage/src/main/java/org/apache/kylin/storage/adhoc/AdHocRunnerBase.java
----------------------------------------------------------------------
diff --git 
a/core-storage/src/main/java/org/apache/kylin/storage/adhoc/AdHocRunnerBase.java
 
b/core-storage/src/main/java/org/apache/kylin/storage/adhoc/AdHocRunnerBase.java
deleted file mode 100644
index 7b870c6..0000000
--- 
a/core-storage/src/main/java/org/apache/kylin/storage/adhoc/AdHocRunnerBase.java
+++ /dev/null
@@ -1,48 +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.storage.adhoc;
-
-import java.util.List;
-
-import org.apache.kylin.common.KylinConfig;
-import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AdHocRunnerBase {
-
-    private static final Logger logger = 
LoggerFactory.getLogger(AdHocRunnerBase.class);
-
-    protected KylinConfig config = null;
-
-    public AdHocRunnerBase() {
-    }
-
-    public AdHocRunnerBase(KylinConfig config) {
-        this.config = config;
-    }
-
-    public void setConfig(KylinConfig config) {
-        this.config = config;
-    }
-
-    public abstract void init();
-
-    public abstract void executeQuery(String query, List<List<String>> 
results, List<SelectedColumnMeta> columnMetas) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/core-storage/src/main/java/org/apache/kylin/storage/adhoc/HiveAdhocConverter.java
----------------------------------------------------------------------
diff --git 
a/core-storage/src/main/java/org/apache/kylin/storage/adhoc/HiveAdhocConverter.java
 
b/core-storage/src/main/java/org/apache/kylin/storage/adhoc/HiveAdhocConverter.java
deleted file mode 100644
index 1a43557..0000000
--- 
a/core-storage/src/main/java/org/apache/kylin/storage/adhoc/HiveAdhocConverter.java
+++ /dev/null
@@ -1,180 +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.storage.adhoc;
-
-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;
-
-//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 {
-
-    private static final Logger logger = 
LoggerFactory.getLogger(HiveAdhocConverter.class);
-
-    private static final Pattern EXTRACT_PATTERN = 
Pattern.compile("\\s+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 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);
-
-    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) + 1;
-            int originEnd = endIdx + 1;
-
-            replacedString = replaceString(replacedString, 
originString.substring(originStart, originEnd), functionStr + "(" + 
extractInner + ")");
-        }
-
-        return replacedString;
-    }
-
-    public static String castRepalce(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 subqueryRepalce(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;
-
-            replacedString = replaceString(replacedString, 
originString.substring(startIdx, endIdx), originString.substring(startIdx, 
endIdx) + " as alias");
-        }
-
-        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 = castRepalce(convertedSql);
-
-        // Step4.Replace sub query
-        convertedSql = subqueryRepalce(convertedSql);
-
-        // Step5.Replace char_length with length
-        convertedSql = replaceString(convertedSql, "char_length", "length");
-
-        // Step6.Replace "||" with concat
-        convertedSql = concatReplace(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/f6cdd629/core-storage/src/main/java/org/apache/kylin/storage/adhoc/IAdhocConverter.java
----------------------------------------------------------------------
diff --git 
a/core-storage/src/main/java/org/apache/kylin/storage/adhoc/IAdhocConverter.java
 
b/core-storage/src/main/java/org/apache/kylin/storage/adhoc/IAdhocConverter.java
deleted file mode 100644
index d5815bb..0000000
--- 
a/core-storage/src/main/java/org/apache/kylin/storage/adhoc/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.storage.adhoc;
-
-/**
- * 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/f6cdd629/core-storage/src/test/java/org/apache/kylin/storage/adhoc/HiveAdhocConverterTest.java
----------------------------------------------------------------------
diff --git 
a/core-storage/src/test/java/org/apache/kylin/storage/adhoc/HiveAdhocConverterTest.java
 
b/core-storage/src/test/java/org/apache/kylin/storage/adhoc/HiveAdhocConverterTest.java
deleted file mode 100644
index 62f6792..0000000
--- 
a/core-storage/src/test/java/org/apache/kylin/storage/adhoc/HiveAdhocConverterTest.java
+++ /dev/null
@@ -1,62 +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.storage.adhoc;
-
-import junit.framework.TestCase;
-import org.junit.Test;
-
-
-public class HiveAdhocConverterTest extends TestCase {
-    @Test
-    public void testSringReplace() {
-        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(replacedString, "select count(*) as cnt from 
test_kylin_fact where length(lstg_format_name) < 10");
-    }
-
-    @Test
-    public void testExtractReplace() {
-        String originString = "ignore EXTRACT(YEAR FROM KYLIN_CAL_DT.CAL_DT) 
ignore";
-        String replacedString = 
HiveAdhocConverter.extractReplace(originString);
-        assertEquals(replacedString, "ignore YEAR(KYLIN_CAL_DT.CAL_DT) 
ignore");
-    }
-
-    @Test
-    public void testCastReplace() {
-        String originString = "ignore EXTRACT(YEAR FROM 
CAST(KYLIN_CAL_DT.CAL_DT AS INTEGER)) ignore";
-        String replacedString = HiveAdhocConverter.castRepalce(originString);
-        assertEquals(replacedString, "ignore EXTRACT(YEAR FROM 
CAST(KYLIN_CAL_DT.CAL_DT AS int)) ignore");
-    }
-
-    @Test
-    public void testSubqueryReplace() {
-        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.subqueryRepalce(originString);
-        assertEquals(replacedString, "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");
-    }
-
-    @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(replacedString, "select count(*) as cnt from 
test_kylin_fact where concat(lstg_format_name,'a')='ABINa'");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/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 8caebc2..83a1ef3 100644
--- a/examples/test_case_data/sandbox/kylin.properties
+++ b/examples/test_case_data/sandbox/kylin.properties
@@ -187,13 +187,13 @@ 
kylin.engine.spark-conf.spark.executor.extraJavaOptions=-Dhdp.version=current
 
 
 ### AD-HOC QUERY ###
-#kylin.query.ad-hoc.runner.class-name=org.apache.kylin.rest.adhoc.AdHocRunnerJdbcImpl
+#kylin.query.ad-hoc.runner-class-name=org.apache.kylin.rest.adhoc.AdHocRunnerJdbcImpl
 
 #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.ad-hoc.pool.max-total=8
-#kylin.query.ad-hoc.pool.max-idle=8
-#kylin.query.ad-hoc.pool.min-idle=0
+#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

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/server-base/src/main/java/org/apache/kylin/rest/adhoc/AdHocRunnerJdbcImpl.java
----------------------------------------------------------------------
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/adhoc/AdHocRunnerJdbcImpl.java
 
b/server-base/src/main/java/org/apache/kylin/rest/adhoc/AdHocRunnerJdbcImpl.java
index 275fce5..44d1770 100644
--- 
a/server-base/src/main/java/org/apache/kylin/rest/adhoc/AdHocRunnerJdbcImpl.java
+++ 
b/server-base/src/main/java/org/apache/kylin/rest/adhoc/AdHocRunnerJdbcImpl.java
@@ -28,34 +28,26 @@ import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.commons.pool.impl.GenericObjectPool;
-import org.apache.kylin.storage.adhoc.AdHocRunnerBase;
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
+import org.apache.kylin.source.adhocquery.IAdHocRunner;
 
-public class AdHocRunnerJdbcImpl extends AdHocRunnerBase {
+public class AdHocRunnerJdbcImpl implements IAdHocRunner {
 
     private static JdbcConnectionPool pool = null;
 
-    public AdHocRunnerJdbcImpl() {
-        super();
-    }
-
-    public AdHocRunnerJdbcImpl(KylinConfig config) {
-        super(config);
-    }
-
     @Override
-    public void init() {
-        if (this.pool == null) {
-            this.pool = new JdbcConnectionPool();
-            JdbcConnectionFactory factory = new 
JdbcConnectionFactory(this.config.getJdbcUrl(), 
this.config.getJdbcDriverClass(), this.config.getJdbcUsername(), 
this.config.getJdbcPassword());
+    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 = this.config.getPoolMaxTotal();
-            poolConfig.maxIdle = this.config.getPoolMaxIdle();
-            poolConfig.minIdle = this.config.getPoolMinIdle();
+            poolConfig.maxActive = config.getPoolMaxTotal();
+            poolConfig.maxIdle = config.getPoolMaxIdle();
+            poolConfig.minIdle = config.getPoolMinIdle();
 
             try {
-                this.pool.createPool(factory, poolConfig);
+                pool.createPool(factory, poolConfig);
             } catch (IOException e) {
                 throw new RuntimeException(e.getMessage(), e);
             }
@@ -96,11 +88,11 @@ public class AdHocRunnerJdbcImpl extends AdHocRunnerBase {
     }
 
     private Connection getConnection() {
-        return this.pool.getConnection();
+        return pool.getConnection();
     }
 
     private void closeConnection(Connection connection) {
-        this.pool.returnConnection(connection);
+        pool.returnConnection(connection);
     }
 
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/server-base/src/main/java/org/apache/kylin/rest/adhoc/JdbcConnectionFactory.java
----------------------------------------------------------------------
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/adhoc/JdbcConnectionFactory.java
 
b/server-base/src/main/java/org/apache/kylin/rest/adhoc/JdbcConnectionFactory.java
index 42613fe..dff98d0 100644
--- 
a/server-base/src/main/java/org/apache/kylin/rest/adhoc/JdbcConnectionFactory.java
+++ 
b/server-base/src/main/java/org/apache/kylin/rest/adhoc/JdbcConnectionFactory.java
@@ -19,12 +19,13 @@
 package org.apache.kylin.rest.adhoc;
 
 
-import org.apache.commons.pool.PoolableObjectFactory;
-
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
 
+import org.apache.commons.pool.PoolableObjectFactory;
+
+@SuppressWarnings("unused")
 class JdbcConnectionFactory implements PoolableObjectFactory {
 
     private final String jdbcUrl;

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
----------------------------------------------------------------------
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
 
b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
index f6bfe3e..0da92c7 100644
--- 
a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
+++ 
b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
@@ -26,10 +26,10 @@ import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.kylin.rest.exception.InternalErrorException;
-import org.apache.kylin.rest.model.Query;
 import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
 import org.apache.kylin.metadata.querymeta.TableMeta;
+import org.apache.kylin.rest.exception.InternalErrorException;
+import org.apache.kylin.rest.model.Query;
 import org.apache.kylin.rest.request.MetaRequest;
 import org.apache.kylin.rest.request.PrepareSqlRequest;
 import org.apache.kylin.rest.request.SQLRequest;
@@ -59,6 +59,7 @@ import org.supercsv.prefs.CsvPreference;
 @Controller
 public class QueryController extends BasicController {
 
+    @SuppressWarnings("unused")
     private static final Logger logger = 
LoggerFactory.getLogger(QueryController.class);
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/kylin/blob/f6cdd629/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 8221790..76ff237 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
@@ -18,8 +18,6 @@
 
 package org.apache.kylin.rest.util;
 
-import static org.apache.kylin.metadata.MetadataManager.CCInfo;
-
 import java.sql.SQLException;
 import java.util.Collections;
 import java.util.List;
@@ -33,15 +31,16 @@ 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.DataModelDesc;
 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.rest.exception.InternalErrorException;
-import org.apache.kylin.storage.adhoc.AdHocRunnerBase;
-import org.apache.kylin.storage.adhoc.IAdhocConverter;
+import org.apache.kylin.source.adhocquery.IAdHocRunner;
+import org.apache.kylin.source.adhocquery.IAdHocConverter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,47 +58,27 @@ public class AdHocUtil {
         boolean isExpectedCause = 
(ExceptionUtils.getRootCause(sqlException).getClass()
                 .equals(NoRealizationFoundException.class));
         KylinConfig kylinConfig = KylinConfig.getInstanceFromEnv();
-        Boolean isAdHoc = false;
 
         if (isExpectedCause && kylinConfig.isAdhocEnabled()) {
-            Class runnerClass = 
Class.forName(kylinConfig.getAdHocRunnerClassName());
-            Class converterClass = 
Class.forName(kylinConfig.getAdHocConverterClassName());
-            Object runnerObj = runnerClass.newInstance();
-            Object converterObj = converterClass.newInstance();
-
-            if (!(runnerObj instanceof AdHocRunnerBase)) {
-                throw new InternalErrorException("Ad-hoc runner class should 
be sub-class of AdHocRunnerBase");
-            }
-
-            if (!(converterObj instanceof IAdhocConverter)) {
-                throw new InternalErrorException("Ad-hoc converter class 
should implement of IAdhocConverter");
-            }
+            IAdHocRunner runner = (IAdHocRunner) 
ClassUtil.newInstance(kylinConfig.getAdHocRunnerClassName());
+            IAdHocConverter converter = (IAdHocConverter) 
ClassUtil.newInstance(kylinConfig.getAdHocConverterClassName());
 
-            AdHocRunnerBase runner = (AdHocRunnerBase) runnerObj;
-            IAdhocConverter converter = (IAdhocConverter) converterObj;
-            runner.setConfig(kylinConfig);
+            runner.init(kylinConfig);
 
-            logger.debug("Ad-hoc query enabled for Kylin");
+            logger.debug("Ad-hoc query runner {}", runner);
 
-            runner.init();
-
-            try {
-                String expandCC = restoreComputedColumnToExpr(sql, project);
-                String adhocSql = converter.convert(expandCC);
-                if (!adhocSql.equals(adhocSql)) {
-                    logger.info("before delegating to adhoc, the query is 
converted to {} ", adhocSql);
-                }
-
-                runner.executeQuery(adhocSql, results, columnMetas);
-                isAdHoc = true;
-            } catch (Exception exception) {
-                throw exception;
+            String expandCC = restoreComputedColumnToExpr(sql, project);
+            String adhocSql = converter.convert(expandCC);
+            if (!adhocSql.equals(sql)) {
+                logger.info("before delegating to adhoc, the query is 
converted to {} ", adhocSql);
             }
+
+            runner.executeQuery(adhocSql, results, columnMetas);
+            
+            return true;
         } else {
             throw sqlException;
         }
-
-        return isAdHoc;
     }
 
     private final static Pattern identifierInSqlPattern = Pattern.compile(

Reply via email to