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:34 UTC
[23/26] kylin git commit: minor, rename adhoc to pushdown in KYLIN
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);
+ }
+ }
+}