mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 12:07:42 +00:00
(improvement)(Headless) Support queryBySql without requiring dataSetId input (#897)
This commit is contained in:
@@ -28,6 +28,8 @@ public interface DataSetService {
|
|||||||
|
|
||||||
List<DataSetResp> getDataSets(User user);
|
List<DataSetResp> getDataSets(User user);
|
||||||
|
|
||||||
|
List<DataSetResp> getDataSets(String dataSetName, User user);
|
||||||
|
|
||||||
List<DataSetResp> getDataSetsInheritAuth(User user, Long domainId);
|
List<DataSetResp> getDataSetsInheritAuth(User user, Long domainId);
|
||||||
|
|
||||||
SemanticQueryReq convert(QueryDataSetReq queryDataSetReq);
|
SemanticQueryReq convert(QueryDataSetReq queryDataSetReq);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -112,6 +113,9 @@ public class DataSetServiceImpl
|
|||||||
if (metaFilter.getStatus() != null) {
|
if (metaFilter.getStatus() != null) {
|
||||||
wrapper.lambda().eq(DataSetDO::getStatus, metaFilter.getStatus());
|
wrapper.lambda().eq(DataSetDO::getStatus, metaFilter.getStatus());
|
||||||
}
|
}
|
||||||
|
if (metaFilter.getName() != null) {
|
||||||
|
wrapper.lambda().eq(DataSetDO::getName, metaFilter.getName());
|
||||||
|
}
|
||||||
wrapper.lambda().ne(DataSetDO::getStatus, StatusEnum.DELETED.getCode());
|
wrapper.lambda().ne(DataSetDO::getStatus, StatusEnum.DELETED.getCode());
|
||||||
return list(wrapper).stream().map(entry -> convert(entry, user)).collect(Collectors.toList());
|
return list(wrapper).stream().map(entry -> convert(entry, user)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
@@ -131,6 +135,14 @@ public class DataSetServiceImpl
|
|||||||
return getDataSetFilterByAuth(dataSetResps, user);
|
return getDataSetFilterByAuth(dataSetResps, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DataSetResp> getDataSets(String dataSetName, User user) {
|
||||||
|
MetaFilter metaFilter = new MetaFilter();
|
||||||
|
metaFilter.setName(dataSetName);
|
||||||
|
List<DataSetResp> dataSetResps = getDataSetList(metaFilter, user);
|
||||||
|
return getDataSetFilterByAuth(dataSetResps, user);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DataSetResp> getDataSetsInheritAuth(User user, Long domainId) {
|
public List<DataSetResp> getDataSetsInheritAuth(User user, Long domainId) {
|
||||||
List<DataSetResp> dataSetResps = getDataSetList(new MetaFilter(), user);
|
List<DataSetResp> dataSetResps = getDataSetList(new MetaFilter(), user);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import com.google.common.collect.Sets;
|
|||||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||||
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
|
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
|
||||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||||
|
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlSelectHelper;
|
||||||
import com.tencent.supersonic.headless.api.pojo.Dim;
|
import com.tencent.supersonic.headless.api.pojo.Dim;
|
||||||
import com.tencent.supersonic.headless.api.pojo.QueryParam;
|
import com.tencent.supersonic.headless.api.pojo.QueryParam;
|
||||||
import com.tencent.supersonic.headless.api.pojo.request.ExplainSqlReq;
|
import com.tencent.supersonic.headless.api.pojo.request.ExplainSqlReq;
|
||||||
@@ -15,6 +17,7 @@ import com.tencent.supersonic.headless.api.pojo.request.QuerySqlReq;
|
|||||||
import com.tencent.supersonic.headless.api.pojo.request.QueryStructReq;
|
import com.tencent.supersonic.headless.api.pojo.request.QueryStructReq;
|
||||||
import com.tencent.supersonic.headless.api.pojo.request.SchemaFilterReq;
|
import com.tencent.supersonic.headless.api.pojo.request.SchemaFilterReq;
|
||||||
import com.tencent.supersonic.headless.api.pojo.request.SemanticQueryReq;
|
import com.tencent.supersonic.headless.api.pojo.request.SemanticQueryReq;
|
||||||
|
import com.tencent.supersonic.headless.api.pojo.response.DataSetResp;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.DimensionResp;
|
import com.tencent.supersonic.headless.api.pojo.response.DimensionResp;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.ExplainResp;
|
import com.tencent.supersonic.headless.api.pojo.response.ExplainResp;
|
||||||
import com.tencent.supersonic.headless.api.pojo.response.ItemUseResp;
|
import com.tencent.supersonic.headless.api.pojo.response.ItemUseResp;
|
||||||
@@ -33,6 +36,7 @@ import com.tencent.supersonic.headless.server.annotation.S2DataPermission;
|
|||||||
import com.tencent.supersonic.headless.server.manager.SemanticSchemaManager;
|
import com.tencent.supersonic.headless.server.manager.SemanticSchemaManager;
|
||||||
import com.tencent.supersonic.headless.server.service.AppService;
|
import com.tencent.supersonic.headless.server.service.AppService;
|
||||||
import com.tencent.supersonic.headless.server.service.Catalog;
|
import com.tencent.supersonic.headless.server.service.Catalog;
|
||||||
|
import com.tencent.supersonic.headless.server.service.DataSetService;
|
||||||
import com.tencent.supersonic.headless.server.service.QueryService;
|
import com.tencent.supersonic.headless.server.service.QueryService;
|
||||||
import com.tencent.supersonic.headless.server.utils.QueryReqConverter;
|
import com.tencent.supersonic.headless.server.utils.QueryReqConverter;
|
||||||
import com.tencent.supersonic.headless.server.utils.QueryUtils;
|
import com.tencent.supersonic.headless.server.utils.QueryUtils;
|
||||||
@@ -61,6 +65,7 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
private final SemanticSchemaManager semanticSchemaManager;
|
private final SemanticSchemaManager semanticSchemaManager;
|
||||||
private final QueryParser queryParser;
|
private final QueryParser queryParser;
|
||||||
private final QueryPlanner queryPlanner;
|
private final QueryPlanner queryPlanner;
|
||||||
|
private final DataSetService dataSetService;
|
||||||
|
|
||||||
public QueryServiceImpl(
|
public QueryServiceImpl(
|
||||||
StatUtils statUtils,
|
StatUtils statUtils,
|
||||||
@@ -70,7 +75,8 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
AppService appService,
|
AppService appService,
|
||||||
SemanticSchemaManager semanticSchemaManager,
|
SemanticSchemaManager semanticSchemaManager,
|
||||||
DefaultQueryParser queryParser,
|
DefaultQueryParser queryParser,
|
||||||
QueryPlanner queryPlanner) {
|
QueryPlanner queryPlanner,
|
||||||
|
DataSetService dataSetService) {
|
||||||
this.statUtils = statUtils;
|
this.statUtils = statUtils;
|
||||||
this.queryUtils = queryUtils;
|
this.queryUtils = queryUtils;
|
||||||
this.queryReqConverter = queryReqConverter;
|
this.queryReqConverter = queryReqConverter;
|
||||||
@@ -79,6 +85,7 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
this.semanticSchemaManager = semanticSchemaManager;
|
this.semanticSchemaManager = semanticSchemaManager;
|
||||||
this.queryParser = queryParser;
|
this.queryParser = queryParser;
|
||||||
this.queryPlanner = queryPlanner;
|
this.queryPlanner = queryPlanner;
|
||||||
|
this.dataSetService = dataSetService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -99,7 +106,7 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
}
|
}
|
||||||
StatUtils.get().setUseResultCache(false);
|
StatUtils.get().setUseResultCache(false);
|
||||||
//3 query
|
//3 query
|
||||||
QueryStatement queryStatement = buildQueryStatement(queryReq);
|
QueryStatement queryStatement = buildQueryStatement(queryReq, user);
|
||||||
SemanticQueryResp result = query(queryStatement);
|
SemanticQueryResp result = query(queryStatement);
|
||||||
//4 reset cache and set stateInfo
|
//4 reset cache and set stateInfo
|
||||||
Boolean setCacheSuccess = queryCache.put(cacheKey, result);
|
Boolean setCacheSuccess = queryCache.put(cacheKey, result);
|
||||||
@@ -128,7 +135,12 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryStatement buildSqlQueryStatement(QuerySqlReq querySqlReq) throws Exception {
|
private QueryStatement buildSqlQueryStatement(QuerySqlReq querySqlReq, User user) throws Exception {
|
||||||
|
//If dataSetId or DataSetName is empty, parse dataSetId from the SQL
|
||||||
|
if (needGetDataSetId(querySqlReq)) {
|
||||||
|
Long dataSetId = getDataSetIdFromSql(querySqlReq, user);
|
||||||
|
querySqlReq.setDataSetId(dataSetId);
|
||||||
|
}
|
||||||
SchemaFilterReq filter = buildSchemaFilterReq(querySqlReq);
|
SchemaFilterReq filter = buildSchemaFilterReq(querySqlReq);
|
||||||
SemanticSchemaResp semanticSchemaResp = catalog.fetchSemanticSchema(filter);
|
SemanticSchemaResp semanticSchemaResp = catalog.fetchSemanticSchema(filter);
|
||||||
QueryStatement queryStatement = queryReqConverter.convert(querySqlReq, semanticSchemaResp);
|
QueryStatement queryStatement = queryReqConverter.convert(querySqlReq, semanticSchemaResp);
|
||||||
@@ -139,15 +151,36 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
return queryStatement;
|
return queryStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryStatement buildQueryStatement(SemanticQueryReq semanticQueryReq) throws Exception {
|
private static boolean needGetDataSetId(QuerySqlReq querySqlReq) {
|
||||||
|
return (Objects.isNull(querySqlReq.getDataSetId()) || querySqlReq.getDataSetId() <= 0)
|
||||||
|
&& (CollectionUtils.isEmpty(querySqlReq.getModelIds()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getDataSetIdFromSql(QuerySqlReq querySqlReq, User user) {
|
||||||
|
List<DataSetResp> dataSets = null;
|
||||||
|
try {
|
||||||
|
String tableName = SqlSelectHelper.getTableName(querySqlReq.getSql());
|
||||||
|
dataSets = dataSetService.getDataSets(tableName, user);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("getDataSetIdFromSql error:{}", e);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isEmpty(dataSets)) {
|
||||||
|
throw new InvalidArgumentException("从Sql参数中无法获取到DataSetId");
|
||||||
|
}
|
||||||
|
Long dataSetId = dataSets.get(0).getId();
|
||||||
|
log.info("getDataSetIdFromSql dataSetId:{}", dataSetId);
|
||||||
|
return dataSetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryStatement buildQueryStatement(SemanticQueryReq semanticQueryReq, User user) throws Exception {
|
||||||
if (semanticQueryReq instanceof QuerySqlReq) {
|
if (semanticQueryReq instanceof QuerySqlReq) {
|
||||||
return buildSqlQueryStatement((QuerySqlReq) semanticQueryReq);
|
return buildSqlQueryStatement((QuerySqlReq) semanticQueryReq, user);
|
||||||
}
|
}
|
||||||
if (semanticQueryReq instanceof QueryStructReq) {
|
if (semanticQueryReq instanceof QueryStructReq) {
|
||||||
return buildStructQueryStatement((QueryStructReq) semanticQueryReq);
|
return buildStructQueryStatement((QueryStructReq) semanticQueryReq);
|
||||||
}
|
}
|
||||||
if (semanticQueryReq instanceof QueryMultiStructReq) {
|
if (semanticQueryReq instanceof QueryMultiStructReq) {
|
||||||
return buildMultiStructQueryStatement((QueryMultiStructReq) semanticQueryReq);
|
return buildMultiStructQueryStatement((QueryMultiStructReq) semanticQueryReq, user);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -167,11 +200,11 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
return queryStatement;
|
return queryStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryStatement buildMultiStructQueryStatement(QueryMultiStructReq queryMultiStructReq)
|
private QueryStatement buildMultiStructQueryStatement(QueryMultiStructReq queryMultiStructReq, User user)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
List<QueryStatement> sqlParsers = new ArrayList<>();
|
List<QueryStatement> sqlParsers = new ArrayList<>();
|
||||||
for (QueryStructReq queryStructReq : queryMultiStructReq.getQueryStructReqs()) {
|
for (QueryStructReq queryStructReq : queryMultiStructReq.getQueryStructReqs()) {
|
||||||
QueryStatement queryStatement = buildQueryStatement(queryStructReq);
|
QueryStatement queryStatement = buildQueryStatement(queryStructReq, user);
|
||||||
SemanticModel semanticModel = queryStatement.getSemanticModel();
|
SemanticModel semanticModel = queryStatement.getSemanticModel();
|
||||||
queryStatement.setModelIds(queryStructReq.getModelIds());
|
queryStatement.setModelIds(queryStructReq.getModelIds());
|
||||||
queryStatement.setSemanticModel(semanticModel);
|
queryStatement.setSemanticModel(semanticModel);
|
||||||
@@ -206,7 +239,7 @@ public class QueryServiceImpl implements QueryService {
|
|||||||
@Override
|
@Override
|
||||||
public <T> ExplainResp explain(ExplainSqlReq<T> explainSqlReq, User user) throws Exception {
|
public <T> ExplainResp explain(ExplainSqlReq<T> explainSqlReq, User user) throws Exception {
|
||||||
T queryReq = explainSqlReq.getQueryReq();
|
T queryReq = explainSqlReq.getQueryReq();
|
||||||
QueryStatement queryStatement = buildQueryStatement((SemanticQueryReq) queryReq);
|
QueryStatement queryStatement = buildQueryStatement((SemanticQueryReq) queryReq, user);
|
||||||
queryStatement = plan(queryStatement);
|
queryStatement = plan(queryStatement);
|
||||||
return getExplainResp(queryStatement);
|
return getExplainResp(queryStatement);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user