(improvement)(semantic) metric table add agg option

This commit is contained in:
jipengli
2023-10-11 14:44:54 +08:00
parent 6b2a14e589
commit c14d4e59d4
9 changed files with 50 additions and 17 deletions

View File

@@ -0,0 +1,15 @@
package com.tencent.supersonic.semantic.api.query.enums;
public enum AggOption {
NATIVE,
AGGREGATION,
DEFAULT;
public static AggOption getAggregation(boolean isNativeQuery) {
return isNativeQuery ? NATIVE : AGGREGATION;
}
public static boolean isAgg(AggOption aggOption) {
return NATIVE.equals(aggOption) ? false : true;
}
}

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.semantic.api.query.pojo; package com.tencent.supersonic.semantic.api.query.pojo;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import java.util.List; import java.util.List;
import lombok.Data; import lombok.Data;
@@ -10,6 +11,6 @@ public class MetricTable {
private List<String> metrics; private List<String> metrics;
private List<String> dimensions; private List<String> dimensions;
private String where; private String where;
private boolean isAgg = false; private AggOption aggOption = AggOption.DEFAULT;
} }

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.semantic.query.parser; package com.tencent.supersonic.semantic.query.parser;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.pojo.MetricTable; import com.tencent.supersonic.semantic.api.query.pojo.MetricTable;
import com.tencent.supersonic.semantic.api.query.request.MetricReq; import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq; import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq;
@@ -60,7 +61,7 @@ public class QueryParser {
metricReq.setDimensions(metricTable.getDimensions()); metricReq.setDimensions(metricTable.getDimensions());
metricReq.setWhere(formatWhere(metricTable.getWhere())); metricReq.setWhere(formatWhere(metricTable.getWhere()));
metricReq.setRootPath(sqlCommend.getRootPath()); metricReq.setRootPath(sqlCommend.getRootPath());
QueryStatement tableSql = parser(metricReq, metricTable.isAgg()); QueryStatement tableSql = parser(metricReq, metricTable.getAggOption());
if (!tableSql.isOk()) { if (!tableSql.isOk()) {
queryStatement.setErrMsg(String.format("parser table [%s] error [%s]", metricTable.getAlias(), queryStatement.setErrMsg(String.format("parser table [%s] error [%s]", metricTable.getAlias(),
tableSql.getErrMsg())); tableSql.getErrMsg()));
@@ -96,10 +97,10 @@ public class QueryParser {
} }
public QueryStatement parser(MetricReq metricCommand) { public QueryStatement parser(MetricReq metricCommand) {
return parser(metricCommand, !metricCommand.isNativeQuery()); return parser(metricCommand, AggOption.getAggregation(metricCommand.isNativeQuery()));
} }
public QueryStatement parser(MetricReq metricCommand, boolean isAgg) { public QueryStatement parser(MetricReq metricCommand, AggOption isAgg) {
log.info("parser MetricReq [{}] isAgg [{}]", metricCommand, isAgg); log.info("parser MetricReq [{}] isAgg [{}]", metricCommand, isAgg);
QueryStatement queryStatement = new QueryStatement(); QueryStatement queryStatement = new QueryStatement();
if (metricCommand.getRootPath().isEmpty()) { if (metricCommand.getRootPath().isEmpty()) {

View File

@@ -1,9 +1,10 @@
package com.tencent.supersonic.semantic.query.parser; package com.tencent.supersonic.semantic.query.parser;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.request.MetricReq; import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.model.domain.Catalog; import com.tencent.supersonic.semantic.model.domain.Catalog;
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement; import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
public interface SqlParser { public interface SqlParser {
QueryStatement explain(MetricReq metricReq, boolean isAgg, Catalog catalog) throws Exception; QueryStatement explain(MetricReq metricReq, AggOption aggOption, Catalog catalog) throws Exception;
} }

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.semantic.query.parser.calcite; package com.tencent.supersonic.semantic.query.parser.calcite;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.request.MetricReq; import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.model.domain.Catalog; import com.tencent.supersonic.semantic.model.domain.Catalog;
import com.tencent.supersonic.semantic.query.parser.SqlParser; import com.tencent.supersonic.semantic.query.parser.SqlParser;
@@ -19,7 +20,7 @@ public class CalciteSqlParser implements SqlParser {
} }
@Override @Override
public QueryStatement explain(MetricReq metricReq, boolean isAgg, Catalog catalog) throws Exception { public QueryStatement explain(MetricReq metricReq, AggOption isAgg, Catalog catalog) throws Exception {
QueryStatement queryStatement = new QueryStatement(); QueryStatement queryStatement = new QueryStatement();
SemanticModel semanticModel = semanticSchemaManager.get(metricReq.getRootPath()); SemanticModel semanticModel = semanticSchemaManager.get(metricReq.getRootPath());
if (semanticModel == null) { if (semanticModel == null) {

View File

@@ -1,6 +1,7 @@
package com.tencent.supersonic.semantic.query.parser.calcite.planner; package com.tencent.supersonic.semantic.query.parser.calcite.planner;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.request.MetricReq; import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Constants; import com.tencent.supersonic.semantic.query.parser.calcite.dsl.Constants;
import com.tencent.supersonic.semantic.query.parser.calcite.dsl.DataSource; import com.tencent.supersonic.semantic.query.parser.calcite.dsl.DataSource;
@@ -30,7 +31,8 @@ public class AggPlanner implements Planner {
private Stack<TableView> dataSets = new Stack<>(); private Stack<TableView> dataSets = new Stack<>();
private SqlNode parserNode; private SqlNode parserNode;
private String sourceId; private String sourceId;
private boolean isAgg = true; private boolean isAgg = false;
private AggOption aggOption = AggOption.DEFAULT;
public AggPlanner(SemanticSchema schema) { public AggPlanner(SemanticSchema schema) {
this.schema = schema; this.schema = schema;
@@ -44,10 +46,7 @@ public class AggPlanner implements Planner {
if (datasource == null || datasource.isEmpty()) { if (datasource == null || datasource.isEmpty()) {
throw new Exception("datasource not found"); throw new Exception("datasource not found");
} }
if (Objects.nonNull(datasource.get(0).getAggTime()) && !datasource.get(0).getAggTime().equalsIgnoreCase( isAgg = getAgg(datasource.get(0));
Constants.DIMENSION_TYPE_TIME_GRANULARITY_NONE)) {
isAgg = true;
}
sourceId = String.valueOf(datasource.get(0).getSourceId()); sourceId = String.valueOf(datasource.get(0).getSourceId());
// build level by level // build level by level
@@ -78,9 +77,21 @@ public class AggPlanner implements Planner {
return DataSourceNode.getMatchDataSources(scope, schema, metricCommand); return DataSourceNode.getMatchDataSources(scope, schema, metricCommand);
} }
private boolean getAgg(DataSource dataSource) {
if (!AggOption.DEFAULT.equals(aggOption)) {
return AggOption.isAgg(aggOption);
}
// default by dataSource time aggregation
if (Objects.nonNull(dataSource.getAggTime()) && !dataSource.getAggTime().equalsIgnoreCase(
Constants.DIMENSION_TYPE_TIME_GRANULARITY_NONE)) {
return true;
}
return isAgg;
}
@Override @Override
public void explain(MetricReq metricCommand, boolean isAgg) throws Exception { public void explain(MetricReq metricCommand, AggOption aggOption) throws Exception {
this.metricCommand = metricCommand; this.metricCommand = metricCommand;
if (metricCommand.getMetrics() == null) { if (metricCommand.getMetrics() == null) {
metricCommand.setMetrics(new ArrayList<>()); metricCommand.setMetrics(new ArrayList<>());
@@ -91,7 +102,7 @@ public class AggPlanner implements Planner {
if (metricCommand.getLimit() == null) { if (metricCommand.getLimit() == null) {
metricCommand.setLimit(0L); metricCommand.setLimit(0L);
} }
this.isAgg = isAgg; this.aggOption = aggOption;
// build a parse Node // build a parse Node
parse(); parse();
// optimizer // optimizer

View File

@@ -1,11 +1,12 @@
package com.tencent.supersonic.semantic.query.parser.calcite.planner; package com.tencent.supersonic.semantic.query.parser.calcite.planner;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.request.MetricReq; import com.tencent.supersonic.semantic.api.query.request.MetricReq;
public interface Planner { public interface Planner {
public void explain(MetricReq metricCommand, boolean isAgg) throws Exception; public void explain(MetricReq metricCommand, AggOption aggOption) throws Exception;
public String getSql(); public String getSql();

View File

@@ -6,6 +6,7 @@ import com.tencent.supersonic.common.pojo.Constants;
import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum; import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum;
import com.tencent.supersonic.common.util.ContextUtils; import com.tencent.supersonic.common.util.ContextUtils;
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp; import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.pojo.MetricTable; import com.tencent.supersonic.semantic.api.query.pojo.MetricTable;
import com.tencent.supersonic.semantic.api.query.request.MetricReq; import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq; import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq;
@@ -75,7 +76,7 @@ public class CalculateAggConverter implements SemanticConverter {
String where = queryStructUtils.generateWhere(queryStructCmd); String where = queryStructUtils.generateWhere(queryStructCmd);
log.info("in generateSqlCommand, complete where:{}", where); log.info("in generateSqlCommand, complete where:{}", where);
metricTable.setWhere(where); metricTable.setWhere(where);
metricTable.setAgg(true); metricTable.setAggOption(AggOption.AGGREGATION);
sqlCommand.setTables(new ArrayList<>(Collections.singletonList(metricTable))); sqlCommand.setTables(new ArrayList<>(Collections.singletonList(metricTable)));
String sql = String.format("select %s from %s %s %s %s", sqlGenerateUtils.getSelect(queryStructCmd), String sql = String.format("select %s from %s %s %s %s", sqlGenerateUtils.getSelect(queryStructCmd),
metricTableName, metricTableName,
@@ -159,7 +160,7 @@ public class CalculateAggConverter implements SemanticConverter {
String where = queryStructUtils.generateWhere(queryStructCmd); String where = queryStructUtils.generateWhere(queryStructCmd);
log.info("in generateSqlCommend, complete where:{}", where); log.info("in generateSqlCommend, complete where:{}", where);
metricTable.setWhere(where); metricTable.setWhere(where);
metricTable.setAgg(true); metricTable.setAggOption(AggOption.AGGREGATION);
sqlCommand.setTables(new ArrayList<>(Collections.singletonList(metricTable))); sqlCommand.setTables(new ArrayList<>(Collections.singletonList(metricTable)));
boolean isOver = isOverRatio(queryStructCmd); boolean isOver = isOverRatio(queryStructCmd);
String sql = ""; String sql = "";

View File

@@ -8,6 +8,7 @@ import com.tencent.supersonic.semantic.api.model.yaml.MeasureYamlTpl;
import com.tencent.supersonic.semantic.api.model.yaml.MetricTypeParamsYamlTpl; import com.tencent.supersonic.semantic.api.model.yaml.MetricTypeParamsYamlTpl;
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl; import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
import com.tencent.supersonic.semantic.api.model.response.SqlParserResp; import com.tencent.supersonic.semantic.api.model.response.SqlParserResp;
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
import com.tencent.supersonic.semantic.api.query.request.MetricReq; import com.tencent.supersonic.semantic.api.query.request.MetricReq;
import com.tencent.supersonic.common.pojo.ColumnOrder; import com.tencent.supersonic.common.pojo.ColumnOrder;
import com.tencent.supersonic.semantic.query.parser.calcite.SemanticSchemaManager; import com.tencent.supersonic.semantic.query.parser.calcite.SemanticSchemaManager;
@@ -37,7 +38,7 @@ class SemanticParserServiceTest {
return sqlParser; return sqlParser;
} }
AggPlanner aggBuilder = new AggPlanner(semanticSchema); AggPlanner aggBuilder = new AggPlanner(semanticSchema);
aggBuilder.explain(metricCommand, isAgg); aggBuilder.explain(metricCommand, AggOption.getAggregation(!isAgg));
sqlParser.setSql(aggBuilder.getSql()); sqlParser.setSql(aggBuilder.getSql());
sqlParser.setSourceId(aggBuilder.getSourceId()); sqlParser.setSourceId(aggBuilder.getSourceId());
} catch (Exception e) { } catch (Exception e) {