mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-12 04:27:39 +00:00
(improvement)(Headless) queryBySql supports Time Correct. (#915)
This commit is contained in:
@@ -1,17 +1,24 @@
|
|||||||
package com.tencent.supersonic.headless.core.chat.corrector;
|
package com.tencent.supersonic.headless.core.chat.corrector;
|
||||||
|
|
||||||
|
|
||||||
|
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||||
import com.tencent.supersonic.common.util.jsqlparser.DateVisitor.DateBoundInfo;
|
import com.tencent.supersonic.common.util.jsqlparser.DateVisitor.DateBoundInfo;
|
||||||
import com.tencent.supersonic.common.util.jsqlparser.SqlAddHelper;
|
import com.tencent.supersonic.common.util.jsqlparser.SqlAddHelper;
|
||||||
import com.tencent.supersonic.common.util.jsqlparser.SqlDateSelectHelper;
|
import com.tencent.supersonic.common.util.jsqlparser.SqlDateSelectHelper;
|
||||||
import com.tencent.supersonic.common.util.jsqlparser.SqlReplaceHelper;
|
import com.tencent.supersonic.common.util.jsqlparser.SqlReplaceHelper;
|
||||||
|
import com.tencent.supersonic.common.util.jsqlparser.SqlSelectHelper;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
||||||
import com.tencent.supersonic.headless.core.pojo.QueryContext;
|
import com.tencent.supersonic.headless.core.pojo.QueryContext;
|
||||||
|
import com.tencent.supersonic.headless.core.utils.S2SqlDateHelper;
|
||||||
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.parser.CCJSqlParserUtil;
|
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,12 +30,39 @@ public class TimeCorrector extends BaseSemanticCorrector {
|
|||||||
@Override
|
@Override
|
||||||
public void doCorrect(QueryContext queryContext, SemanticParseInfo semanticParseInfo) {
|
public void doCorrect(QueryContext queryContext, SemanticParseInfo semanticParseInfo) {
|
||||||
|
|
||||||
|
addDateIfNotExist(queryContext, semanticParseInfo);
|
||||||
|
|
||||||
parserDateDiffFunction(semanticParseInfo);
|
parserDateDiffFunction(semanticParseInfo);
|
||||||
|
|
||||||
addLowerBoundDate(semanticParseInfo);
|
addLowerBoundDate(semanticParseInfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addDateIfNotExist(QueryContext queryContext, SemanticParseInfo semanticParseInfo) {
|
||||||
|
String correctS2SQL = semanticParseInfo.getSqlInfo().getCorrectS2SQL();
|
||||||
|
List<String> whereFields = SqlSelectHelper.getWhereFields(correctS2SQL);
|
||||||
|
if (CollectionUtils.isEmpty(whereFields) || !TimeDimensionEnum.containsZhTimeDimension(whereFields)) {
|
||||||
|
|
||||||
|
Pair<String, String> startEndDate = S2SqlDateHelper.getStartEndDate(queryContext,
|
||||||
|
semanticParseInfo.getDataSetId(), semanticParseInfo.getQueryType());
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(startEndDate.getLeft())
|
||||||
|
&& StringUtils.isNotBlank(startEndDate.getRight())) {
|
||||||
|
correctS2SQL = SqlAddHelper.addParenthesisToWhere(correctS2SQL);
|
||||||
|
String dateChName = TimeDimensionEnum.DAY.getChName();
|
||||||
|
String condExpr = String.format(" ( %s >= '%s' and %s <= '%s' )", dateChName,
|
||||||
|
startEndDate.getLeft(), dateChName, startEndDate.getRight());
|
||||||
|
try {
|
||||||
|
Expression expression = CCJSqlParserUtil.parseCondExpression(condExpr);
|
||||||
|
correctS2SQL = SqlAddHelper.addWhere(correctS2SQL, expression);
|
||||||
|
} catch (JSQLParserException e) {
|
||||||
|
log.error("parseCondExpression:{}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
semanticParseInfo.getSqlInfo().setCorrectS2SQL(correctS2SQL);
|
||||||
|
}
|
||||||
|
|
||||||
private void addLowerBoundDate(SemanticParseInfo semanticParseInfo) {
|
private void addLowerBoundDate(SemanticParseInfo semanticParseInfo) {
|
||||||
String correctS2SQL = semanticParseInfo.getSqlInfo().getCorrectS2SQL();
|
String correctS2SQL = semanticParseInfo.getSqlInfo().getCorrectS2SQL();
|
||||||
DateBoundInfo dateBoundInfo = SqlDateSelectHelper.getDateBoundInfo(correctS2SQL);
|
DateBoundInfo dateBoundInfo = SqlDateSelectHelper.getDateBoundInfo(correctS2SQL);
|
||||||
|
|||||||
@@ -2,24 +2,20 @@ package com.tencent.supersonic.headless.core.chat.corrector;
|
|||||||
|
|
||||||
|
|
||||||
import com.tencent.supersonic.common.pojo.Constants;
|
import com.tencent.supersonic.common.pojo.Constants;
|
||||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
|
||||||
import com.tencent.supersonic.common.util.StringUtil;
|
import com.tencent.supersonic.common.util.StringUtil;
|
||||||
import com.tencent.supersonic.common.util.jsqlparser.SqlAddHelper;
|
import com.tencent.supersonic.common.util.jsqlparser.SqlAddHelper;
|
||||||
import com.tencent.supersonic.common.util.jsqlparser.SqlReplaceHelper;
|
import com.tencent.supersonic.common.util.jsqlparser.SqlReplaceHelper;
|
||||||
import com.tencent.supersonic.common.util.jsqlparser.SqlSelectHelper;
|
|
||||||
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
|
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SchemaValueMap;
|
import com.tencent.supersonic.headless.api.pojo.SchemaValueMap;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SemanticSchema;
|
import com.tencent.supersonic.headless.api.pojo.SemanticSchema;
|
||||||
import com.tencent.supersonic.headless.api.pojo.request.QueryFilters;
|
import com.tencent.supersonic.headless.api.pojo.request.QueryFilters;
|
||||||
import com.tencent.supersonic.headless.core.pojo.QueryContext;
|
import com.tencent.supersonic.headless.core.pojo.QueryContext;
|
||||||
import com.tencent.supersonic.headless.core.utils.S2SqlDateHelper;
|
|
||||||
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;
|
||||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.apache.logging.log4j.util.Strings;
|
import org.apache.logging.log4j.util.Strings;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@@ -38,8 +34,6 @@ public class WhereCorrector extends BaseSemanticCorrector {
|
|||||||
@Override
|
@Override
|
||||||
public void doCorrect(QueryContext queryContext, SemanticParseInfo semanticParseInfo) {
|
public void doCorrect(QueryContext queryContext, SemanticParseInfo semanticParseInfo) {
|
||||||
|
|
||||||
addDateIfNotExist(queryContext, semanticParseInfo);
|
|
||||||
|
|
||||||
addQueryFilter(queryContext, semanticParseInfo);
|
addQueryFilter(queryContext, semanticParseInfo);
|
||||||
|
|
||||||
updateFieldValueByTechName(queryContext, semanticParseInfo);
|
updateFieldValueByTechName(queryContext, semanticParseInfo);
|
||||||
@@ -63,31 +57,6 @@ public class WhereCorrector extends BaseSemanticCorrector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDateIfNotExist(QueryContext queryContext, SemanticParseInfo semanticParseInfo) {
|
|
||||||
String correctS2SQL = semanticParseInfo.getSqlInfo().getCorrectS2SQL();
|
|
||||||
List<String> whereFields = SqlSelectHelper.getWhereFields(correctS2SQL);
|
|
||||||
if (CollectionUtils.isEmpty(whereFields) || !TimeDimensionEnum.containsZhTimeDimension(whereFields)) {
|
|
||||||
|
|
||||||
Pair<String, String> startEndDate = S2SqlDateHelper.getStartEndDate(queryContext,
|
|
||||||
semanticParseInfo.getDataSetId(), semanticParseInfo.getQueryType());
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(startEndDate.getLeft())
|
|
||||||
&& StringUtils.isNotBlank(startEndDate.getRight())) {
|
|
||||||
correctS2SQL = SqlAddHelper.addParenthesisToWhere(correctS2SQL);
|
|
||||||
String dateChName = TimeDimensionEnum.DAY.getChName();
|
|
||||||
String condExpr = String.format(" ( %s >= '%s' and %s <= '%s' )", dateChName,
|
|
||||||
startEndDate.getLeft(), dateChName, startEndDate.getRight());
|
|
||||||
try {
|
|
||||||
Expression expression = CCJSqlParserUtil.parseCondExpression(condExpr);
|
|
||||||
correctS2SQL = SqlAddHelper.addWhere(correctS2SQL, expression);
|
|
||||||
} catch (JSQLParserException e) {
|
|
||||||
log.error("parseCondExpression:{}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
semanticParseInfo.getSqlInfo().setCorrectS2SQL(correctS2SQL);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getQueryFilter(QueryFilters queryFilters) {
|
private String getQueryFilter(QueryFilters queryFilters) {
|
||||||
if (Objects.isNull(queryFilters) || CollectionUtils.isEmpty(queryFilters.getFilters())) {
|
if (Objects.isNull(queryFilters) || CollectionUtils.isEmpty(queryFilters.getFilters())) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.tencent.supersonic.headless.server.rest.api;
|
|||||||
|
|
||||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||||
|
import com.tencent.supersonic.common.pojo.enums.QueryType;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SemanticSchema;
|
import com.tencent.supersonic.headless.api.pojo.SemanticSchema;
|
||||||
import com.tencent.supersonic.headless.api.pojo.SqlInfo;
|
import com.tencent.supersonic.headless.api.pojo.SqlInfo;
|
||||||
@@ -71,6 +72,7 @@ public class SqlQueryApiController {
|
|||||||
sqlInfo.setCorrectS2SQL(querySqlReq.getSql());
|
sqlInfo.setCorrectS2SQL(querySqlReq.getSql());
|
||||||
sqlInfo.setS2SQL(querySqlReq.getSql());
|
sqlInfo.setS2SQL(querySqlReq.getSql());
|
||||||
semanticParseInfo.setSqlInfo(sqlInfo);
|
semanticParseInfo.setSqlInfo(sqlInfo);
|
||||||
|
semanticParseInfo.setQueryType(QueryType.TAG);
|
||||||
|
|
||||||
ComponentFactory.getSemanticCorrectors().forEach(corrector -> {
|
ComponentFactory.getSemanticCorrectors().forEach(corrector -> {
|
||||||
if (!(corrector instanceof GrammarCorrector)) {
|
if (!(corrector instanceof GrammarCorrector)) {
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ public class DimensionServiceImpl implements DimensionService {
|
|||||||
String forbiddenCharacters = NameCheckUtils.findForbiddenCharacters(dimensionReq.getName());
|
String forbiddenCharacters = NameCheckUtils.findForbiddenCharacters(dimensionReq.getName());
|
||||||
if (StringUtils.isNotBlank(forbiddenCharacters)) {
|
if (StringUtils.isNotBlank(forbiddenCharacters)) {
|
||||||
throw new InvalidArgumentException(String.format("名称包含特殊字符, 请修改: %s,特殊字符: %s",
|
throw new InvalidArgumentException(String.format("名称包含特殊字符, 请修改: %s,特殊字符: %s",
|
||||||
dimensionReq.getBizName(), forbiddenCharacters));
|
dimensionReq.getName(), forbiddenCharacters));
|
||||||
}
|
}
|
||||||
if (bizNameMap.containsKey(dimensionReq.getBizName())) {
|
if (bizNameMap.containsKey(dimensionReq.getBizName())) {
|
||||||
DimensionResp dimensionResp = bizNameMap.get(dimensionReq.getBizName());
|
DimensionResp dimensionResp = bizNameMap.get(dimensionReq.getBizName());
|
||||||
|
|||||||
Reference in New Issue
Block a user