From 372e4acc2c9adeefed594c61e16a6a6293adec79 Mon Sep 17 00:00:00 2001 From: jipeli <54889677+jipeli@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:57:38 +0800 Subject: [PATCH] (improvement)(semantic) fixed withAs not supported on CK version lower than 20.4 (#305) Co-authored-by: jipengli --- .../supersonic/common/util/StringUtil.java | 21 ++++++++++++++ .../parser/convert/CalculateAggConverter.java | 28 ++++++++++++------- .../query/utils/QueryStructUtils.java | 12 ++++++-- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/common/src/main/java/com/tencent/supersonic/common/util/StringUtil.java b/common/src/main/java/com/tencent/supersonic/common/util/StringUtil.java index c5a8a0ca0..f3a28c647 100644 --- a/common/src/main/java/com/tencent/supersonic/common/util/StringUtil.java +++ b/common/src/main/java/com/tencent/supersonic/common/util/StringUtil.java @@ -25,4 +25,25 @@ public class StringUtil { return where.replace("\"", "\\\\\""); } + /** + * + * @param v1 + * @param v2 + * @return value 0 if v1 equal to v2; less than 0 if v1 is less than v2; greater than 0 if v1 is greater than v2 + */ + public static int compareVersion(String v1, String v2) { + String[] v1s = v1.split("\\."); + String[] v2s = v2.split("\\."); + int length = Math.min(v1s.length, v2s.length); + for (int i = 0; i < length; i++) { + Integer vv1 = Integer.parseInt(v1s[i]); + Integer vv2 = Integer.parseInt(v2s[i]); + int compare = vv1.compareTo(vv2); + if (compare != 0) { + return compare; + } + } + return v1s.length - v2s.length; + } + } \ No newline at end of file diff --git a/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/parser/convert/CalculateAggConverter.java b/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/parser/convert/CalculateAggConverter.java index 413ee56ef..190066c83 100644 --- a/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/parser/convert/CalculateAggConverter.java +++ b/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/parser/convert/CalculateAggConverter.java @@ -44,7 +44,6 @@ public class CalculateAggConverter implements SemanticConverter { private String metricAggDefault; - public CalculateAggConverter( SemanticQueryEngine parserService, @Lazy QueryStructUtils queryStructUtils, @@ -57,7 +56,7 @@ public class CalculateAggConverter implements SemanticConverter { public interface EngineSql { - String sql(QueryStructReq queryStructCmd, boolean isOver, String metricSql); + String sql(QueryStructReq queryStructCmd, boolean isOver, boolean asWith, String metricSql); } public ParseSqlReq generateSqlCommend(QueryStructReq queryStructCmd, EngineTypeEnum engineTypeEnum, String version) @@ -166,16 +165,18 @@ public class CalculateAggConverter implements SemanticConverter { String sql = ""; switch (engineTypeEnum) { case H2: - sql = new H2EngineSql().sql(queryStructCmd, isOver, metricTableName); + sql = new H2EngineSql().sql(queryStructCmd, isOver, true, metricTableName); break; case MYSQL: case DORIS: case CLICKHOUSE: if (!queryStructUtils.isSupportWith(engineTypeEnum, version)) { sqlCommand.setSupportWith(false); - sql = new MysqlEngineSql().sql(queryStructCmd, isOver, metricTableName); + } + if (!engineTypeEnum.equals(engineTypeEnum.CLICKHOUSE)) { + sql = new MysqlEngineSql().sql(queryStructCmd, isOver, sqlCommand.isSupportWith(), metricTableName); } else { - sql = new CkEngineSql().sql(queryStructCmd, isOver, metricTableName); + sql = new CkEngineSql().sql(queryStructCmd, isOver, sqlCommand.isSupportWith(), metricTableName); } break; default: @@ -248,7 +249,7 @@ public class CalculateAggConverter implements SemanticConverter { } @Override - public String sql(QueryStructReq queryStructCmd, boolean isOver, String metricSql) { + public String sql(QueryStructReq queryStructCmd, boolean isOver, boolean asWith, String metricSql) { String sql = String.format( "select %s from ( select %s , %s from %s t0 left join %s t1 on %s ) metric_tb_src %s %s ", getOverSelect(queryStructCmd, isOver), getAllSelect(queryStructCmd, "t0."), @@ -292,15 +293,22 @@ public class CalculateAggConverter implements SemanticConverter { } @Override - public String sql(QueryStructReq queryStructCmd, boolean isOver, String metricSql) { - String sql = String.format( + public String sql(QueryStructReq queryStructCmd, boolean isOver, boolean asWith, String metricSql) { + if (!asWith) { + return String.format( + "select %s from ( select %s , %s from %s t0 left join %s t1 on %s ) metric_tb_src %s %s ", + getOverSelect(queryStructCmd, isOver), getAllSelect(queryStructCmd, "t0."), + getAllJoinSelect(queryStructCmd, "t1."), metricSql, metricSql, + getJoinOn(queryStructCmd, isOver, "t0.", "t1."), + getOrderBy(queryStructCmd), getLimit(queryStructCmd)); + } + return String.format( ",t0 as (select * from %s),t1 as (select * from %s) select %s from ( select %s , %s " + "from t0 left join t1 on %s ) metric_tb_src %s %s ", metricSql, metricSql, getOverSelect(queryStructCmd, isOver), getAllSelect(queryStructCmd, "t0."), getAllJoinSelect(queryStructCmd, "t1."), getJoinOn(queryStructCmd, isOver, "t0.", "t1."), getOrderBy(queryStructCmd), getLimit(queryStructCmd)); - return sql; } } @@ -368,7 +376,7 @@ public class CalculateAggConverter implements SemanticConverter { } @Override - public String sql(QueryStructReq queryStructCmd, boolean isOver, String metricSql) { + public String sql(QueryStructReq queryStructCmd, boolean isOver, boolean asWith, String metricSql) { String sql = String.format( "select %s from ( select %s , %s from %s t0 left join %s t1 on %s ) metric_tb_src %s %s ", getOverSelect(queryStructCmd, isOver), getAllSelect(queryStructCmd, "t0."), diff --git a/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/utils/QueryStructUtils.java b/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/utils/QueryStructUtils.java index 1576226aa..74b0b07eb 100644 --- a/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/utils/QueryStructUtils.java +++ b/semantic/query/src/main/java/com/tencent/supersonic/semantic/query/utils/QueryStructUtils.java @@ -11,10 +11,11 @@ import com.tencent.supersonic.common.pojo.Aggregator; import com.tencent.supersonic.common.pojo.DateConf; import com.tencent.supersonic.common.pojo.DateConf.DateMode; import com.tencent.supersonic.common.pojo.enums.TypeEnums; +import com.tencent.supersonic.common.util.StringUtil; import com.tencent.supersonic.common.util.jsqlparser.FilterExpression; -import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper; -import com.tencent.supersonic.common.util.jsqlparser.SqlParserRemoveHelper; import com.tencent.supersonic.common.util.jsqlparser.SqlParserAddHelper; +import com.tencent.supersonic.common.util.jsqlparser.SqlParserRemoveHelper; +import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper; import com.tencent.supersonic.semantic.api.model.pojo.ItemDateFilter; import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem; import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq; @@ -73,6 +74,8 @@ public class QueryStructUtils { private String internalMetricNameSuffix; @Value("${metricParser.agg.mysql.lowVersion:5.7}") private String mysqlLowVersion; + @Value("${metricParser.agg.ck.lowVersion:20.4}") + private String ckLowVersion; @Autowired private SchemaService schemaService; @@ -263,6 +266,11 @@ public class QueryStructUtils { mysqlLowVersion)) { return false; } + if (engineTypeEnum.equals(EngineTypeEnum.CLICKHOUSE) && Objects.nonNull(version) + && StringUtil.compareVersion(version, + ckLowVersion) < 0) { + return false; + } return true; }