(improvement)(headless) fix derived metric parse error (#665)

This commit is contained in:
jipeli
2024-01-19 21:30:27 +08:00
committed by GitHub
parent 1ef1aa53a3
commit c154f476cb
6 changed files with 46 additions and 10 deletions

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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();
}
} }

View File

@@ -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 {

View File

@@ -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));
} }

View File

@@ -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;