mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-12 12:37:55 +00:00
(improvement)(chat) support show sum metric in chinese name and support multiple conditions in having and if not exist metirc than not addAggregateToMetric (#165)
This commit is contained in:
@@ -30,8 +30,6 @@ public class GlobalBeforeCorrector extends BaseSemanticCorrector {
|
|||||||
correctFieldName(semanticCorrectInfo);
|
correctFieldName(semanticCorrectInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void replaceAlias(SemanticCorrectInfo semanticCorrectInfo) {
|
private void replaceAlias(SemanticCorrectInfo semanticCorrectInfo) {
|
||||||
String replaceAlias = SqlParserUpdateHelper.replaceAlias(semanticCorrectInfo.getSql());
|
String replaceAlias = SqlParserUpdateHelper.replaceAlias(semanticCorrectInfo.getSql());
|
||||||
semanticCorrectInfo.setSql(replaceAlias);
|
semanticCorrectInfo.setSql(replaceAlias);
|
||||||
|
|||||||
@@ -30,21 +30,18 @@ public class GroupByCorrector extends BaseSemanticCorrector {
|
|||||||
|
|
||||||
if (!CollectionUtils.isEmpty(selectFields)
|
if (!CollectionUtils.isEmpty(selectFields)
|
||||||
&& !CollectionUtils.isEmpty(metrics)
|
&& !CollectionUtils.isEmpty(metrics)
|
||||||
&& selectFields.stream().anyMatch(s -> metrics.contains(s))) {
|
&& !selectFields.stream().anyMatch(s -> metrics.contains(s))) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//add aggregate to all metric
|
//add aggregate to all metric
|
||||||
addAggregateToMetric(semanticCorrectInfo);
|
addAggregateToMetric(semanticCorrectInfo);
|
||||||
|
}
|
||||||
|
|
||||||
//add dimension group by
|
//add dimension group by
|
||||||
String sql = semanticCorrectInfo.getSql();
|
String sql = semanticCorrectInfo.getSql();
|
||||||
SemanticSchema semanticSchema = ContextUtils.getBean(SchemaService.class).getSemanticSchema();
|
SemanticSchema semanticSchema = ContextUtils.getBean(SchemaService.class).getSemanticSchema();
|
||||||
|
|
||||||
Set<String> dimensions = semanticSchema.getDimensions(modelId).stream()
|
Set<String> dimensions = semanticSchema.getDimensions(modelId).stream()
|
||||||
.filter(schemaElement -> !DateUtils.DATE_FIELD.equals(schemaElement.getBizName()))
|
|
||||||
.map(schemaElement -> schemaElement.getName()).collect(Collectors.toSet());
|
.map(schemaElement -> schemaElement.getName()).collect(Collectors.toSet());
|
||||||
|
dimensions.add(DateUtils.DATE_FIELD);
|
||||||
selectFields = SqlParserSelectHelper.getSelectFields(sql);
|
selectFields = SqlParserSelectHelper.getSelectFields(sql);
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(selectFields) || CollectionUtils.isEmpty(dimensions)) {
|
if (CollectionUtils.isEmpty(selectFields) || CollectionUtils.isEmpty(dimensions)) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.tencent.supersonic.common.util.jsqlparser;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.sf.jsqlparser.JSQLParserException;
|
import net.sf.jsqlparser.JSQLParserException;
|
||||||
import net.sf.jsqlparser.expression.Expression;
|
import net.sf.jsqlparser.expression.Expression;
|
||||||
@@ -32,8 +33,12 @@ public class GroupByReplaceVisitor implements GroupByVisitor {
|
|||||||
|
|
||||||
for (int i = 0; i < groupByExpressions.size(); i++) {
|
for (int i = 0; i < groupByExpressions.size(); i++) {
|
||||||
Expression expression = groupByExpressions.get(i);
|
Expression expression = groupByExpressions.get(i);
|
||||||
|
String columnName = expression.toString();
|
||||||
String replaceColumn = parseVisitorHelper.getReplaceColumn(expression.toString(), fieldNameMap,
|
if (expression instanceof Function && Objects.nonNull(
|
||||||
|
((Function) expression).getParameters().getExpressions().get(0))) {
|
||||||
|
columnName = ((Function) expression).getParameters().getExpressions().get(0).toString();
|
||||||
|
}
|
||||||
|
String replaceColumn = parseVisitorHelper.getReplaceColumn(columnName, fieldNameMap,
|
||||||
exactReplace);
|
exactReplace);
|
||||||
if (StringUtils.isNotEmpty(replaceColumn)) {
|
if (StringUtils.isNotEmpty(replaceColumn)) {
|
||||||
if (expression instanceof Column) {
|
if (expression instanceof Column) {
|
||||||
|
|||||||
@@ -468,7 +468,12 @@ public class SqlParserUpdateHelper {
|
|||||||
List<Expression> waitingForAdds = visitor.getWaitingForAdds();
|
List<Expression> waitingForAdds = visitor.getWaitingForAdds();
|
||||||
if (!CollectionUtils.isEmpty(waitingForAdds)) {
|
if (!CollectionUtils.isEmpty(waitingForAdds)) {
|
||||||
for (Expression waitingForAdd : waitingForAdds) {
|
for (Expression waitingForAdd : waitingForAdds) {
|
||||||
|
Expression having = plainSelect.getHaving();
|
||||||
|
if (Objects.isNull(having)) {
|
||||||
plainSelect.setHaving(waitingForAdd);
|
plainSelect.setHaving(waitingForAdd);
|
||||||
|
} else {
|
||||||
|
plainSelect.setHaving(new AndExpression(having, waitingForAdd));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return selectStatement.toString();
|
return selectStatement.toString();
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class QueryReqConverter {
|
|||||||
Map<String, String> fieldNameToBizNameMap = getFieldNameToBizNameMap(modelSchemaResp);
|
Map<String, String> fieldNameToBizNameMap = getFieldNameToBizNameMap(modelSchemaResp);
|
||||||
String sql = databaseReq.getSql();
|
String sql = databaseReq.getSql();
|
||||||
log.info("convert name to bizName before:{}", sql);
|
log.info("convert name to bizName before:{}", sql);
|
||||||
String replaceFields = SqlParserUpdateHelper.replaceFields(sql, fieldNameToBizNameMap, true);
|
String replaceFields = SqlParserUpdateHelper.replaceFields(sql, fieldNameToBizNameMap, false);
|
||||||
log.info("convert name to bizName after:{}", replaceFields);
|
log.info("convert name to bizName after:{}", replaceFields);
|
||||||
databaseReq.setSql(replaceFields);
|
databaseReq.setSql(replaceFields);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package com.tencent.supersonic.semantic.query.utils;
|
|||||||
import static com.tencent.supersonic.common.pojo.Constants.JOIN_UNDERLINE;
|
import static com.tencent.supersonic.common.pojo.Constants.JOIN_UNDERLINE;
|
||||||
import static com.tencent.supersonic.common.pojo.Constants.UNIONALL;
|
import static com.tencent.supersonic.common.pojo.Constants.UNIONALL;
|
||||||
|
|
||||||
import com.tencent.supersonic.common.pojo.Constants;
|
|
||||||
import com.tencent.supersonic.common.pojo.Aggregator;
|
import com.tencent.supersonic.common.pojo.Aggregator;
|
||||||
|
import com.tencent.supersonic.common.pojo.Constants;
|
||||||
|
import com.tencent.supersonic.common.pojo.QueryColumn;
|
||||||
import com.tencent.supersonic.common.util.cache.CacheUtils;
|
import com.tencent.supersonic.common.util.cache.CacheUtils;
|
||||||
import com.tencent.supersonic.semantic.api.model.enums.TimeDimensionEnum;
|
import com.tencent.supersonic.semantic.api.model.enums.TimeDimensionEnum;
|
||||||
import com.tencent.supersonic.common.pojo.QueryColumn;
|
|
||||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||||
@@ -22,6 +22,7 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@@ -36,10 +37,13 @@ import org.springframework.util.CollectionUtils;
|
|||||||
@Component
|
@Component
|
||||||
public class QueryUtils {
|
public class QueryUtils {
|
||||||
|
|
||||||
|
private static final String pattern = "\\(`(.*?)`\\)";
|
||||||
|
|
||||||
|
private static final String no_quotation_pattern = "\\((.*?)\\)";
|
||||||
|
|
||||||
private final Set<Pattern> patterns = new HashSet<>();
|
private final Set<Pattern> patterns = new HashSet<>();
|
||||||
@Value("${query.cache.enable:true}")
|
@Value("${query.cache.enable:true}")
|
||||||
private Boolean cacheEnable;
|
private Boolean cacheEnable;
|
||||||
|
|
||||||
private final CacheUtils cacheUtils;
|
private final CacheUtils cacheUtils;
|
||||||
private final StatUtils statUtils;
|
private final StatUtils statUtils;
|
||||||
|
|
||||||
@@ -86,6 +90,15 @@ public class QueryUtils {
|
|||||||
}
|
}
|
||||||
if (namePair.containsKey(nameEn)) {
|
if (namePair.containsKey(nameEn)) {
|
||||||
column.setName(namePair.get(nameEn));
|
column.setName(namePair.get(nameEn));
|
||||||
|
} else {
|
||||||
|
String nameEnByRegex = getNameEnByRegex(nameEn, pattern);
|
||||||
|
if (StringUtils.isEmpty(nameEnByRegex)) {
|
||||||
|
nameEnByRegex = getNameEnByRegex(nameEn, no_quotation_pattern);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(nameEnByRegex) && StringUtils.isNotEmpty(namePair.get(nameEnByRegex))) {
|
||||||
|
String filedName = namePair.get(nameEnByRegex);
|
||||||
|
column.setName(nameEn.replaceAll(nameEnByRegex, filedName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nameTypePair.containsKey(nameEn)) {
|
if (nameTypePair.containsKey(nameEn)) {
|
||||||
column.setShowType(nameTypePair.get(nameEn));
|
column.setShowType(nameTypePair.get(nameEn));
|
||||||
@@ -103,6 +116,7 @@ public class QueryUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void fillItemNameInfo(QueryResultWithSchemaResp queryResultWithColumns,
|
public void fillItemNameInfo(QueryResultWithSchemaResp queryResultWithColumns,
|
||||||
QueryMultiStructReq queryMultiStructCmd) {
|
QueryMultiStructReq queryMultiStructCmd) {
|
||||||
List<Aggregator> aggregators = queryMultiStructCmd.getQueryStructReqs().stream()
|
List<Aggregator> aggregators = queryMultiStructCmd.getQueryStructReqs().stream()
|
||||||
@@ -142,6 +156,17 @@ public class QueryUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getNameEnByRegex(String nameEn, String pattern) {
|
||||||
|
Pattern p = Pattern.compile(pattern);
|
||||||
|
Matcher m = p.matcher(nameEn);
|
||||||
|
|
||||||
|
if (m.find()) {
|
||||||
|
String result = m.group(1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isNumberType(String type) {
|
private boolean isNumberType(String type) {
|
||||||
if (StringUtils.isBlank(type)) {
|
if (StringUtils.isBlank(type)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user