mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-13 13:07:32 +00:00
(improvement)(headless) fix derived metric parse error (#665)
This commit is contained in:
@@ -9,10 +9,12 @@ import java.util.stream.Collectors;
|
|||||||
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.BinaryExpression;
|
import net.sf.jsqlparser.expression.BinaryExpression;
|
||||||
|
import net.sf.jsqlparser.expression.CaseExpression;
|
||||||
import net.sf.jsqlparser.expression.Expression;
|
import net.sf.jsqlparser.expression.Expression;
|
||||||
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
|
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
|
||||||
import net.sf.jsqlparser.expression.Function;
|
import net.sf.jsqlparser.expression.Function;
|
||||||
import net.sf.jsqlparser.expression.StringValue;
|
import net.sf.jsqlparser.expression.StringValue;
|
||||||
|
import net.sf.jsqlparser.expression.WhenClause;
|
||||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||||
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
|
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
|
||||||
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
|
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
|
||||||
@@ -500,6 +502,18 @@ public class SqlParserSelectHelper {
|
|||||||
getColumnFromExpr(expr, columns);
|
getColumnFromExpr(expr, columns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (expression instanceof CaseExpression) {
|
||||||
|
CaseExpression expr = (CaseExpression) expression;
|
||||||
|
if (Objects.nonNull(expr.getWhenClauses())) {
|
||||||
|
for (WhenClause whenClause : expr.getWhenClauses()) {
|
||||||
|
getColumnFromExpr(whenClause.getWhenExpression(), columns);
|
||||||
|
getColumnFromExpr(whenClause.getThenExpression(), columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Objects.nonNull(expr.getElseExpression())) {
|
||||||
|
getColumnFromExpr(expr.getElseExpression(), columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (expression instanceof BinaryExpression) {
|
if (expression instanceof BinaryExpression) {
|
||||||
BinaryExpression expr = (BinaryExpression) expression;
|
BinaryExpression expr = (BinaryExpression) expression;
|
||||||
getColumnFromExpr(expr.getLeftExpression(), columns);
|
getColumnFromExpr(expr.getLeftExpression(), columns);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class MetricTypeParams {
|
|||||||
private List<Measure> measures;
|
private List<Measure> measures;
|
||||||
private List<Measure> metrics;
|
private List<Measure> metrics;
|
||||||
private List<Measure> fields;
|
private List<Measure> fields;
|
||||||
|
private boolean isFieldMetric = false;
|
||||||
private String expr;
|
private String expr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package com.tencent.supersonic.headless.core.parser.calcite.sql.node;
|
|||||||
|
|
||||||
|
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.s2sql.Metric;
|
import com.tencent.supersonic.headless.core.parser.calcite.s2sql.Metric;
|
||||||
|
import com.tencent.supersonic.headless.core.parser.calcite.schema.SemanticSchema;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.apache.calcite.sql.SqlNode;
|
import org.apache.calcite.sql.SqlNode;
|
||||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||||
@@ -26,4 +28,14 @@ public class MetricNode extends SemanticNode {
|
|||||||
return buildAs(metric.getName(), sqlNode);
|
return buildAs(metric.getName(), sqlNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Boolean isMetricField(String name, SemanticSchema schema) {
|
||||||
|
Optional<Metric> metric = schema.getMetrics().stream().filter(m -> m.getName().equalsIgnoreCase(name))
|
||||||
|
.findFirst();
|
||||||
|
return metric.isPresent() && metric.get().getMetricTypeParams().isFieldMetric();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isMetricField(Metric metric) {
|
||||||
|
return metric.getMetricTypeParams().isFieldMetric();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,17 +11,16 @@ import com.tencent.supersonic.headless.core.parser.calcite.sql.TableView;
|
|||||||
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.FilterNode;
|
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.FilterNode;
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.MetricNode;
|
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.MetricNode;
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.SemanticNode;
|
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.SemanticNode;
|
||||||
import org.apache.calcite.sql.SqlIdentifier;
|
|
||||||
import org.apache.calcite.sql.SqlNode;
|
|
||||||
import org.apache.calcite.sql.parser.SqlParserPos;
|
|
||||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.calcite.sql.SqlIdentifier;
|
||||||
|
import org.apache.calcite.sql.SqlNode;
|
||||||
|
import org.apache.calcite.sql.parser.SqlParserPos;
|
||||||
|
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* process query specified filtering information
|
* process query specified filtering information
|
||||||
@@ -30,7 +29,7 @@ public class FilterRender extends Renderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(MetricQueryReq metricCommand, List<DataSource> dataSources, SqlValidatorScope scope,
|
public void render(MetricQueryReq metricCommand, List<DataSource> dataSources, SqlValidatorScope scope,
|
||||||
SemanticSchema schema, boolean nonAgg) throws Exception {
|
SemanticSchema schema, boolean nonAgg) throws Exception {
|
||||||
TableView tableView = super.tableView;
|
TableView tableView = super.tableView;
|
||||||
SqlNode filterNode = null;
|
SqlNode filterNode = null;
|
||||||
List<String> queryMetrics = new ArrayList<>(metricCommand.getMetrics());
|
List<String> queryMetrics = new ArrayList<>(metricCommand.getMetrics());
|
||||||
@@ -54,6 +53,10 @@ public class FilterRender extends Renderer {
|
|||||||
}
|
}
|
||||||
for (String metric : queryMetrics) {
|
for (String metric : queryMetrics) {
|
||||||
Optional<Metric> optionalMetric = Renderer.getMetricByName(metric, schema);
|
Optional<Metric> optionalMetric = Renderer.getMetricByName(metric, schema);
|
||||||
|
if (optionalMetric.isPresent() && MetricNode.isMetricField(optionalMetric.get())) {
|
||||||
|
// metric from field ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (optionalMetric.isPresent()) {
|
if (optionalMetric.isPresent()) {
|
||||||
tableView.getMeasure().add(MetricNode.build(optionalMetric.get(), scope));
|
tableView.getMeasure().add(MetricNode.build(optionalMetric.get(), scope));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package com.tencent.supersonic.headless.core.parser.calcite.sql.render;
|
package com.tencent.supersonic.headless.core.parser.calcite.sql.render;
|
||||||
|
|
||||||
|
|
||||||
import com.tencent.supersonic.headless.api.request.MetricQueryReq;
|
|
||||||
import com.tencent.supersonic.common.pojo.ColumnOrder;
|
import com.tencent.supersonic.common.pojo.ColumnOrder;
|
||||||
|
import com.tencent.supersonic.headless.api.request.MetricQueryReq;
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.s2sql.DataSource;
|
import com.tencent.supersonic.headless.core.parser.calcite.s2sql.DataSource;
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.schema.SemanticSchema;
|
import com.tencent.supersonic.headless.core.parser.calcite.schema.SemanticSchema;
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.sql.Renderer;
|
import com.tencent.supersonic.headless.core.parser.calcite.sql.Renderer;
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.sql.TableView;
|
import com.tencent.supersonic.headless.core.parser.calcite.sql.TableView;
|
||||||
|
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.MetricNode;
|
||||||
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.SemanticNode;
|
import com.tencent.supersonic.headless.core.parser.calcite.sql.node.SemanticNode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.calcite.sql.SqlNode;
|
import org.apache.calcite.sql.SqlNode;
|
||||||
@@ -25,12 +25,16 @@ public class OutputRender extends Renderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(MetricQueryReq metricCommand, List<DataSource> dataSources, SqlValidatorScope scope,
|
public void render(MetricQueryReq metricCommand, List<DataSource> dataSources, SqlValidatorScope scope,
|
||||||
SemanticSchema schema, boolean nonAgg) throws Exception {
|
SemanticSchema schema, boolean nonAgg) throws Exception {
|
||||||
TableView selectDataSet = super.tableView;
|
TableView selectDataSet = super.tableView;
|
||||||
for (String dimension : metricCommand.getDimensions()) {
|
for (String dimension : metricCommand.getDimensions()) {
|
||||||
selectDataSet.getMeasure().add(SemanticNode.parse(dimension, scope));
|
selectDataSet.getMeasure().add(SemanticNode.parse(dimension, scope));
|
||||||
}
|
}
|
||||||
for (String metric : metricCommand.getMetrics()) {
|
for (String metric : metricCommand.getMetrics()) {
|
||||||
|
if (MetricNode.isMetricField(metric, schema)) {
|
||||||
|
// metric from field ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
selectDataSet.getMeasure().add(SemanticNode.parse(metric, scope));
|
selectDataSet.getMeasure().add(SemanticNode.parse(metric, scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,16 +174,19 @@ public class SemanticSchemaManager {
|
|||||||
private static MetricTypeParams getMetricTypeParams(MetricTypeParamsYamlTpl metricTypeParamsYamlTpl) {
|
private static MetricTypeParams getMetricTypeParams(MetricTypeParamsYamlTpl metricTypeParamsYamlTpl) {
|
||||||
MetricTypeParams metricTypeParams = new MetricTypeParams();
|
MetricTypeParams metricTypeParams = new MetricTypeParams();
|
||||||
metricTypeParams.setExpr(metricTypeParamsYamlTpl.getExpr());
|
metricTypeParams.setExpr(metricTypeParamsYamlTpl.getExpr());
|
||||||
|
metricTypeParams.setFieldMetric(false);
|
||||||
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getMeasures())) {
|
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getMeasures())) {
|
||||||
metricTypeParams.setMeasures(getMeasureParams(metricTypeParamsYamlTpl.getMeasures()));
|
metricTypeParams.setMeasures(getMeasureParams(metricTypeParamsYamlTpl.getMeasures()));
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getMetrics())) {
|
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getMetrics())) {
|
||||||
metricTypeParams.setMeasures(getMetricParams(metricTypeParamsYamlTpl.getMetrics()));
|
metricTypeParams.setMeasures(getMetricParams(metricTypeParamsYamlTpl.getMetrics()));
|
||||||
metricTypeParams.setExpr(metricTypeParams.getMeasures().get(0).getExpr());
|
metricTypeParams.setExpr(metricTypeParams.getMeasures().get(0).getExpr());
|
||||||
|
metricTypeParams.setFieldMetric(true);
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getFields())) {
|
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getFields())) {
|
||||||
metricTypeParams.setMeasures(getFieldParams(metricTypeParamsYamlTpl.getFields()));
|
metricTypeParams.setMeasures(getFieldParams(metricTypeParamsYamlTpl.getFields()));
|
||||||
metricTypeParams.setExpr(metricTypeParams.getMeasures().get(0).getExpr());
|
metricTypeParams.setExpr(metricTypeParams.getMeasures().get(0).getExpr());
|
||||||
|
metricTypeParams.setFieldMetric(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return metricTypeParams;
|
return metricTypeParams;
|
||||||
|
|||||||
Reference in New Issue
Block a user