(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 net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.CaseExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
import net.sf.jsqlparser.expression.Function;
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.OrExpression;
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
@@ -500,6 +502,18 @@ public class SqlParserSelectHelper {
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) {
BinaryExpression expr = (BinaryExpression) expression;
getColumnFromExpr(expr.getLeftExpression(), columns);

View File

@@ -9,7 +9,7 @@ public class MetricTypeParams {
private List<Measure> measures;
private List<Measure> metrics;
private List<Measure> fields;
private boolean isFieldMetric = false;
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.schema.SemanticSchema;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import lombok.Data;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.validate.SqlValidatorScope;
@@ -26,4 +28,14 @@ public class MetricNode extends SemanticNode {
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.MetricNode;
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.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
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
@@ -54,6 +53,10 @@ public class FilterRender extends Renderer {
}
for (String metric : queryMetrics) {
Optional<Metric> optionalMetric = Renderer.getMetricByName(metric, schema);
if (optionalMetric.isPresent() && MetricNode.isMetricField(optionalMetric.get())) {
// metric from field ignore
continue;
}
if (optionalMetric.isPresent()) {
tableView.getMeasure().add(MetricNode.build(optionalMetric.get(), scope));
} else {

View File

@@ -1,14 +1,14 @@
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.headless.api.request.MetricQueryReq;
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.sql.Renderer;
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 java.util.ArrayList;
import java.util.List;
import org.apache.calcite.sql.SqlNode;
@@ -31,6 +31,10 @@ public class OutputRender extends Renderer {
selectDataSet.getMeasure().add(SemanticNode.parse(dimension, scope));
}
for (String metric : metricCommand.getMetrics()) {
if (MetricNode.isMetricField(metric, schema)) {
// metric from field ignore
continue;
}
selectDataSet.getMeasure().add(SemanticNode.parse(metric, scope));
}

View File

@@ -174,16 +174,19 @@ public class SemanticSchemaManager {
private static MetricTypeParams getMetricTypeParams(MetricTypeParamsYamlTpl metricTypeParamsYamlTpl) {
MetricTypeParams metricTypeParams = new MetricTypeParams();
metricTypeParams.setExpr(metricTypeParamsYamlTpl.getExpr());
metricTypeParams.setFieldMetric(false);
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getMeasures())) {
metricTypeParams.setMeasures(getMeasureParams(metricTypeParamsYamlTpl.getMeasures()));
}
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getMetrics())) {
metricTypeParams.setMeasures(getMetricParams(metricTypeParamsYamlTpl.getMetrics()));
metricTypeParams.setExpr(metricTypeParams.getMeasures().get(0).getExpr());
metricTypeParams.setFieldMetric(true);
}
if (!CollectionUtils.isEmpty(metricTypeParamsYamlTpl.getFields())) {
metricTypeParams.setMeasures(getFieldParams(metricTypeParamsYamlTpl.getFields()));
metricTypeParams.setExpr(metricTypeParams.getMeasures().get(0).getExpr());
metricTypeParams.setFieldMetric(true);
}
return metricTypeParams;