diff options
| author | wangwei <[email protected]> | 2024-10-18 18:01:18 +0800 |
|---|---|---|
| committer | wangwei <[email protected]> | 2024-10-18 18:01:18 +0800 |
| commit | c8e7346fb906b8173e894600c3e9504b19b6f85d (patch) | |
| tree | 5602249f5eb4495633328d0c70f0502c68c66226 /src | |
| parent | 0f5b53c35fb5b65bb2864d28f772701b6d5e5a3a (diff) | |
[Fix][Jsqlparse] 升级JsqlParser 4.6至5.0(GAL-658)
Diffstat (limited to 'src')
26 files changed, 682 insertions, 722 deletions
diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/AutoPeriodHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/AutoPeriodHelper.java index 9b923e21..62ff32a0 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/AutoPeriodHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/AutoPeriodHelper.java @@ -12,12 +12,15 @@ import com.mesalab.common.utils.SpringContextUtil; import com.mesalab.qgw.constant.DslIdentifierNameConst; import com.mesalab.qgw.model.basic.DSLQueryRequestParam; import com.mesalab.qgw.service.DatabaseService; +import lombok.AllArgsConstructor; +import lombok.Data; import lombok.Getter; import net.sf.jsqlparser.JSQLParserException; 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.operators.relational.ExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.ExplainStatement; import net.sf.jsqlparser.statement.Statement; @@ -64,13 +67,12 @@ public class AutoPeriodHelper { } public static Statement buildSqlGranularity(Statement statement) { - DateTime now = new DateTime(); if (statement instanceof ExplainStatement) { ExplainStatement explainStatement = (ExplainStatement) statement; - buildSelectStatement(now, explainStatement.getStatement()); + buildSelectStatement(explainStatement.getStatement()); return explainStatement; } else if (statement instanceof Select) { - buildSelectStatement(now, (Select) statement); + buildSelectStatement((Select) statement); return statement; } return statement; @@ -99,13 +101,15 @@ public class AutoPeriodHelper { } } - private static void buildSelectStatement(DateTime now, Select select) { + private static void buildSelectStatement(Select select) { + Map<String, String> retentionMap = Maps.newHashMap(); List<String> tableList = SQLHelper.getTableName(select); for (String table : tableList) { buildRetentionMap(retentionMap, table); } - select.getSelectBody().accept(new SelectAdapter(now, retentionMap)); + Context context = new Context(System.currentTimeMillis(), retentionMap); + select.accept(new SelectAdapter<>(), context); } private static void buildRetentionMap(Map<String, String> retentionMap, String table) { @@ -119,7 +123,7 @@ public class AutoPeriodHelper { retentionMap.put(table, String.valueOf(retentions)); } } else { - + retentionMap.put(table, getDefaultRetention()); } } @@ -128,8 +132,8 @@ public class AutoPeriodHelper { Expression expression = CCJSqlParserUtil.parseExpression(granularity); if (expression instanceof Function) { Function fun = (Function) expression; - Expression expression1 = fun.getParameters().getExpressions().get(0); - Expression expression2 = fun.getParameters().getExpressions().get(1); + Expression expression1 = fun.getParameters().get(0); + Expression expression2 = fun.getParameters().get(1); DateTime start = DateUtil.parse(((StringValue) expression1).getValue()); DateTime end = DateUtil.parse(((StringValue) expression2).getValue()); return getGranularityPeriod(new DateTime(), start, end, retentionMap, isChartGranularity); @@ -266,205 +270,188 @@ public class AutoPeriodHelper { return P1D; } - private static class SelectAdapter extends SelectVisitorAdapter { - private final DateTime now; - private final Map<String, String> retentionMap; + private static class SelectAdapter<T> extends SelectVisitorAdapter<T> { - public SelectAdapter(DateTime now, Map<String, String> retentionMap) { - this.now = now; - this.retentionMap = retentionMap; - } @Override - public void visit(PlainSelect plainSelect) { - List<SelectItem> selectItems = plainSelect.getSelectItems(); + public <S> T visit(PlainSelect plainSelect, S context) { + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); if (selectItems != null) { - for (SelectItem selectItem : selectItems) { - SelectItemAdapter selectItemAdapter = new SelectItemAdapter(now, retentionMap); - selectItem.accept(selectItemAdapter); + for (SelectItem<?> selectItem : selectItems) { + selectItem.accept(new SelectItemAdapter<>(), context); } } - FromItem fromItem = plainSelect.getFromItem(); if (fromItem != null) { - fromItem.accept(new FromItemAdapter(now, retentionMap)); + fromItem.accept(new FromItemAdapter<>(), context); } Expression where = plainSelect.getWhere(); if (where != null) { - where.accept(new ExpressionAdapter(now, retentionMap)); + ExpressionAdapter<T> expressionAdapter = new ExpressionAdapter<>(); + expressionAdapter.setSelectVisitor(this); + where.accept(expressionAdapter, context); } GroupByElement groupBy = plainSelect.getGroupBy(); - if (groupBy != null && groupBy.getGroupByExpressionList() != null && !groupBy.getGroupByExpressionList().getExpressions().isEmpty()) { - groupBy.accept(new GroupByAdapter(now, retentionMap)); + if (groupBy != null && groupBy.getGroupByExpressionList() != null && !groupBy.getGroupByExpressionList().isEmpty()) { + groupBy.accept(new GroupByAdapter<>(), context); } Expression having = plainSelect.getHaving(); if (having != null) { - having.accept(new ExpressionAdapter(now, retentionMap)); + having.accept(new ExpressionAdapter<>(), context); } List<OrderByElement> orderByElements = plainSelect.getOrderByElements(); if (orderByElements != null) { for (OrderByElement orderByElement : orderByElements) { - orderByElement.accept(new OrderByAdapter(now, retentionMap)); + orderByElement.accept(new OrderByAdapter<>(), context); } } + return null; } @Override - public void visit(SetOperationList setOpList) { - for (SelectBody select : setOpList.getSelects()) { + public <S> T visit(SetOperationList setOpList, S context) { + for (Select select : setOpList.getSelects()) { if (select instanceof PlainSelect) { - select.accept(this); + select.accept(this, context); } } + return null; } } - private static class SelectItemAdapter extends SelectItemVisitorAdapter { + private static class SelectItemAdapter<T> extends SelectItemVisitorAdapter<T> { - private final DateTime now; - private final Map<String, String> retentionMap; - - public SelectItemAdapter(DateTime now, Map<String, String> retentionMap) { - this.now = now; - this.retentionMap = retentionMap; - } @Override - public void visit(SelectExpressionItem selectExpressionItem) { - Expression expression = selectExpressionItem.getExpression(); - FunctionAdapter functionAdapter = new FunctionAdapter(now, retentionMap); - expression.accept(functionAdapter); + public <S> T visit(SelectItem<? extends Expression> selectItem, S context) { + Expression expression = selectItem.getExpression(); + expression.accept(new FunctionAdapter<>(), context); + return null; } } - private static class FromItemAdapter extends FromItemVisitorAdapter { - private final DateTime now; - private final Map<String, String> retentionMap; - - public FromItemAdapter(DateTime now, Map<String, String> retentionMap) { - this.now = now; - this.retentionMap = retentionMap; - } + private static class FromItemAdapter<T> extends FromItemVisitorAdapter<T> { @Override - public void visit(SubSelect subSelect) { - SelectBody selectBody = subSelect.getSelectBody(); - selectBody.accept(new SelectAdapter(now, retentionMap)); + public <S> T visit(ParenthesedSelect parenthesedSelect, S context) { + Select select = parenthesedSelect.getSelect(); + if (select instanceof PlainSelect) { + select.getPlainSelect().accept(new SelectAdapter<>(), context); + } else if (select instanceof SetOperationList) { + select.getSetOperationList().accept(new SelectAdapter<>(), context); + } + return null; } } - private static class ExpressionAdapter extends ExpressionVisitorAdapter { - private final DateTime now; - private final Map<String, String> retentionMap; - - public ExpressionAdapter(DateTime now, Map<String, String> retentionMap) { - this.now = now; - this.retentionMap = retentionMap; - } + private static class ExpressionAdapter<T> extends ExpressionVisitorAdapter<T> { @Override - public void visit(SubSelect subSelect) { - SelectBody selectBody = subSelect.getSelectBody(); - selectBody.accept(new SelectAdapter(now, retentionMap)); + public <S> T visit(ParenthesedSelect parenthesedSelect, S context) { + Select select = parenthesedSelect.getSelect(); + if (select instanceof PlainSelect) { + select.getPlainSelect().accept(new SelectAdapter<>(), context); + } else if (select instanceof SetOperationList) { + select.getSetOperationList().accept(new SelectAdapter<>(), context); + } + return null; } @Override - public void visit(Function function) { - FunctionAdapter functionAdapter = new FunctionAdapter(now, retentionMap); - function.accept(functionAdapter); + public <S> T visit(Function function, S context) { + function.accept(new FunctionAdapter<>(), context); + return null; } } - private static class GroupByAdapter implements GroupByVisitor { - private final DateTime now; - private final Map<String, String> retentionMap; - - public GroupByAdapter(DateTime now, Map<String, String> retentionMap) { - this.now = now; - this.retentionMap = retentionMap; - } + private static class GroupByAdapter<T> implements GroupByVisitor<T> { @Override - public void visit(GroupByElement groupByElement) { + public <S> T visit(GroupByElement groupByElement, S context) { if (groupByElement.getGroupByExpressionList() == null - || groupByElement.getGroupByExpressionList().getExpressions() == null) { - return; + || groupByElement.getGroupByExpressionList().isEmpty()) { + return null; } - for (Expression expression : groupByElement.getGroupByExpressionList().getExpressions()) { - FunctionAdapter functionAdapter = new FunctionAdapter(now, retentionMap); - expression.accept(functionAdapter); + for (Object obj : groupByElement.getGroupByExpressionList()) { + if (obj instanceof Expression) { + Expression expression = (Expression) obj; + expression.accept(new FunctionAdapter<>(), context); + } + } + return null; } } - private static class OrderByAdapter implements OrderByVisitor { - private final DateTime now; - private final Map<String, String> retentionMap; - - public OrderByAdapter(DateTime now, Map<String, String> retentionMap) { - this.now = now; - this.retentionMap = retentionMap; - } + private static class OrderByAdapter<T> implements OrderByVisitor<T> { @Override - public void visit(OrderByElement orderBy) { + public <S> T visit(OrderByElement orderBy, S context) { if (orderBy.getExpression() == null) { - return; + return null; } - FunctionAdapter functionAdapter = new FunctionAdapter(now, retentionMap); - orderBy.getExpression().accept(functionAdapter); - + orderBy.getExpression().accept(new FunctionAdapter<>(), context); + return null; } } - private static class FunctionAdapter extends ExpressionVisitorAdapter { - - private final DateTime now; - private final Map<String, String> retentionMap; - - public FunctionAdapter(DateTime now, Map<String, String> retentionMap) { - this.now = now; - this.retentionMap = retentionMap; - } + private static class FunctionAdapter<T> extends ExpressionVisitorAdapter<T> { @Override - public void visit(Function function) { + public <S> T visit(Function function, S context) { if (isTimeFloorWithFill(function)) { - buildNewFunction(function); + if (context instanceof Context) { + buildNewFunction(function, (Context) context); + } } else if (isDatetimeFloorWithFill(function)) { - buildNewFunction(function); + if (context instanceof Context) { + buildNewFunction(function, (Context) context); + } } else if (isRate(function)) { - buildNewFunction(function); + if (context instanceof Context) { + buildNewFunction(function, (Context) context); + } } else if (isBitRate(function)) { - buildNewFunction(function); + if (context instanceof Context) { + buildNewFunction(function, (Context) context); + } } else { Optional.ofNullable(function.getParameters()).ifPresent(o -> { - for (Expression expression : o.getExpressions()) { - expression.accept(this); - } + o.accept(this, context); }); } + return null; } - private void buildNewFunction(Function function) { - Expression period = function.getParameters().getExpressions().get(1); + private void buildNewFunction(Function function, Context context) { + Expression period = function.getParameters().get(1); if (isChartGranularity(period)) { Function periodFunction = (Function) period; - DateTime startTime = DateUtil.parse(((StringValue) periodFunction.getParameters().getExpressions().get(0)).getValue()); - DateTime endTime = DateUtil.parse(((StringValue) periodFunction.getParameters().getExpressions().get(1)).getValue()); + DateTime startTime = DateUtil.parse(((StringValue) periodFunction.getParameters().get(0)).getValue()); + DateTime endTime = DateUtil.parse(((StringValue) periodFunction.getParameters().get(1)).getValue()); + long timeSnapshotMills = context.getTimeSnapshotMills(); + DateTime now = new DateTime(timeSnapshotMills); + Map<String, String> retentionMap = context.getRetentions(); String chartGranularityPeriod = getGranularityPeriod(now, startTime, endTime, retentionMap, true); - function.getParameters().getExpressions().set(1, new StringValue("'" + chartGranularityPeriod + "'")); + ExpressionList<Expression> parametersList = (ExpressionList<Expression>) function.getParameters(); + parametersList.set(1, new StringValue("'" + chartGranularityPeriod + "'")); + function.setParameters(parametersList); } else if (isSampleGranularity(period)) { Function periodFunction = (Function) period; - DateTime startTime = DateUtil.parse(((StringValue) periodFunction.getParameters().getExpressions().get(0)).getValue()); - DateTime endTime = DateUtil.parse(((StringValue) periodFunction.getParameters().getExpressions().get(1)).getValue()); + DateTime startTime = DateUtil.parse(((StringValue) periodFunction.getParameters().get(0)).getValue()); + DateTime endTime = DateUtil.parse(((StringValue) periodFunction.getParameters().get(1)).getValue()); + long timeSnapshotMills = context.getTimeSnapshotMills(); + DateTime now = new DateTime(timeSnapshotMills); + Map<String, String> retentionMap = context.getRetentions(); String chartGranularityPeriod = getGranularityPeriod(now, startTime, endTime, retentionMap, false); - function.getParameters().getExpressions().set(1, new StringValue("'" + chartGranularityPeriod + "'")); + ExpressionList<Expression> parametersList = (ExpressionList<Expression>) function.getParameters(); + parametersList.set(1, new StringValue("'" + chartGranularityPeriod + "'")); + function.setParameters(parametersList); } } @@ -476,7 +463,7 @@ public class AutoPeriodHelper { } Function function = (Function) expression; return CHART_GRANULARITY.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() == 2; + && function.getParameters().size() == 2; } private static boolean isSampleGranularity(Expression expression) { @@ -485,7 +472,7 @@ public class AutoPeriodHelper { } Function function = (Function) expression; return SAMPLE_GRANULARITY.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() == 2; + && function.getParameters().size() == 2; } private static boolean isTimeFloorWithFill(Expression expression) { @@ -494,7 +481,7 @@ public class AutoPeriodHelper { } Function function = (Function) expression; return TIME_FLOOR_WITH_FILL.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() >= 2; + && function.getParameters().size() >= 2; } private static boolean isDatetimeFloorWithFill(Expression expression) { @@ -503,7 +490,7 @@ public class AutoPeriodHelper { } Function function = (Function) expression; return DATETIME_FLOOR_WITH_FILL.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() >= 2; + && function.getParameters().size() >= 2; } private static boolean isRate(Expression expression) { @@ -512,7 +499,7 @@ public class AutoPeriodHelper { } Function function = (Function) expression; return RATE.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() >= 2; + && function.getParameters().size() >= 2; } private static boolean isBitRate(Expression expression) { @@ -521,12 +508,15 @@ public class AutoPeriodHelper { } Function function = (Function) expression; return BITRATE.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() >= 2; + && function.getParameters().size() >= 2; } @Getter private enum StorageSchemaRetentionUnitEnum { + /** + * Desc: storage unit display period unit + */ SECOND("s", "PT%sS"), MINUTE("m", "PT%sM"), HOUR("h", "PT%sH"), @@ -540,4 +530,11 @@ public class AutoPeriodHelper { } } + @Data + @AllArgsConstructor + private static class Context { + private long timeSnapshotMills; + private Map<String, String> retentions; + } + } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/ColumnCategoryHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/ColumnCategoryHelper.java index 61705022..36c0e9b1 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/ColumnCategoryHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/ColumnCategoryHelper.java @@ -57,7 +57,7 @@ public class ColumnCategoryHelper { String selectItemExpr = aliasFields.get(field) == null ? SQLFunctionUtil.generateDateFunction(field, dbEngine) : aliasFields.get(field); String dimensionExpr = groupDimension.get(dimensionKey) == null ? SQLFunctionUtil.generateDateFunction(dimensionKey, dbEngine) : groupDimension.get(dimensionKey); if (dimensionExpr != null && selectItemExpr != null) { - ExpressionColumnCollectAdapter selectItemAdapter = new ExpressionColumnCollectAdapter(); + ExpressionColumnCollectAdapter<Object> selectItemAdapter = new ExpressionColumnCollectAdapter<>(); Expression expr1 = CCJSqlParserUtil.parseExpression(selectItemExpr); if (SQLFunctionUtil.pAggregateFunStandard.matcher(expr1.toString()).find()) { map.put(META_CATEGORY, META_CATEGORY_METRIC); @@ -71,12 +71,12 @@ public class ColumnCategoryHelper { map.put(META_CATEGORY, META_CATEGORY_METRIC); continue meta; } - expr1.accept(selectItemAdapter); + expr1.accept(selectItemAdapter, null); Set<String> selectItemColumn = selectItemAdapter.getColumns(); - ExpressionColumnCollectAdapter dimensionAdapter = new ExpressionColumnCollectAdapter(); + ExpressionColumnCollectAdapter<Object> dimensionAdapter = new ExpressionColumnCollectAdapter<>(); Expression expr2 = CCJSqlParserUtil.parseExpression(dimensionExpr); - expr2.accept(dimensionAdapter); + expr2.accept(dimensionAdapter, null); Set<String> dimensionColumn = dimensionAdapter.getColumns(); boolean hasDuplicates = selectItemColumn.stream().anyMatch(dimensionColumn::contains); diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/CondExpressionHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/CondExpressionHelper.java index 5f821b59..f611a0ec 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/CondExpressionHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/CondExpressionHelper.java @@ -33,16 +33,16 @@ public class CondExpressionHelper { */ public static List<String> getDistinctFields(String condExpr) throws JSQLParserException { Expression expr = CCJSqlParserUtil.parseCondExpression(condExpr, false); - ExprFieldParser parser = new ExprFieldParser(); - expr.accept(parser); + ExprFieldParser<Object> parser = new ExprFieldParser<>(); + expr.accept(parser, null); return parser.getList().stream().distinct().collect(Collectors.toList()); } /** * Desc: rewrite conditional expression, replace alias with exact value * - * @param condExpr conditional expression after where - * @param aliasFields key-alias, value-ExactValue + * @param condExpr conditional expression after where + * @param aliasFields key-alias, value-ExactValue * @return {@link Expression} * @created by wWei * @date 2023/3/2 09:52 @@ -50,17 +50,17 @@ public class CondExpressionHelper { public static Expression rewireCondExprBaseOnCK(String condExpr, Map<String, String> aliasFields, boolean updateTable, String table) throws JSQLParserException { Expression expr = CCJSqlParserUtil.parseCondExpression(condExpr, false); ExprActualFieldParser exprParseAlias = new ExprActualFieldParser(aliasFields, updateTable, table); - expr.accept(exprParseAlias); + expr.accept(exprParseAlias, null); return expr; } public static List<String> getDistinctFieldsOfOrderBy(OrderByElement orderByElement) throws JSQLParserException { OrderByFieldParser orderBy = new OrderByFieldParser(); - orderByElement.accept(orderBy); + orderByElement.accept(orderBy, null); return orderBy.getList(); } - private static class ExprFieldParser extends ExpressionVisitorAdapter { + private static class ExprFieldParser<T> extends ExpressionVisitorAdapter<T> { private final List<String> list = Lists.newArrayList(); public List<String> getList() { @@ -68,12 +68,13 @@ public class CondExpressionHelper { } @Override - public void visit(Column column) { + public <S> T visit(Column column, S context) { list.add(SQLHelper.removeQuotesAndBackticks(column.getColumnName())); + return null; } } - private static class ExprActualFieldParser extends ExpressionVisitorAdapter { + private static class ExprActualFieldParser<T> extends ExpressionVisitorAdapter<T> { private final Map<String, String> map; private final Boolean updateTable; private final String tableName; @@ -85,21 +86,22 @@ public class CondExpressionHelper { } @Override - public void visit(Column column) { + public <S> T visit(Column column, S context) { if (column.getTable() != null) { if (updateTable) { column.getTable().setName(tableName); } - return; + return null; } String columnName = SQLHelper.removeQuotesAndBackticks(column.getColumnName()); if (map.containsKey(columnName)) { column.setColumnName(String.valueOf(map.get(columnName))); } + return null; } } - private static class OrderByFieldParser extends OrderByVisitorAdapter { + private static class OrderByFieldParser<T> extends OrderByVisitorAdapter<T> { private final List<String> list = Lists.newArrayList(); public List<String> getList() { @@ -108,8 +110,9 @@ public class CondExpressionHelper { @SneakyThrows @Override - public void visit(OrderByElement orderBy) { + public <S> T visit(OrderByElement orderBy, S context) { list.addAll(getDistinctFields(String.valueOf(orderBy.getExpression()))); + return null; } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/ExpressionColumnCollectAdapter.java b/src/main/java/com/mesalab/common/utils/sqlparser/ExpressionColumnCollectAdapter.java index acea2d6f..b3182fde 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/ExpressionColumnCollectAdapter.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/ExpressionColumnCollectAdapter.java @@ -1,12 +1,10 @@ package com.mesalab.common.utils.sqlparser; -import com.google.common.collect.Lists; import com.google.common.collect.Sets; import lombok.Data; import net.sf.jsqlparser.expression.*; import net.sf.jsqlparser.schema.Column; -import java.util.List; import java.util.Set; @@ -16,14 +14,15 @@ import java.util.Set; * @Author wWei */ @Data -public class ExpressionColumnCollectAdapter extends ExpressionVisitorAdapter { +public class ExpressionColumnCollectAdapter<T> extends ExpressionVisitorAdapter<T> { public Set<String> columns = Sets.newHashSet(); @Override - public void visit(Column column) { + public <S> T visit(Column column, S context) { if (column != null) { this.columns.add(column.getColumnName()); } + return null; } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/FunctionsMergeHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/FunctionsMergeHelper.java index af8e7117..06c752c1 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/FunctionsMergeHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/FunctionsMergeHelper.java @@ -1,5 +1,6 @@ package com.mesalab.common.utils.sqlparser; +import com.google.common.collect.Maps; import lombok.SneakyThrows; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; @@ -42,15 +43,15 @@ public class FunctionsMergeHelper { * 1. FROM_UNIXTIME(TIME_FLOOR_WITH_FILL(UNIX_TIMESTAMP(column), *[, *])) ==> * 1.1 Select Item: TIME_FORMAT(TIME_FLOOR(column, *), 'yyyy-MM-dd HH:mm:ss') * 1.2 GroupBy or Order By Expr: TIME_FLOOR(column, *) - * + * <p> * 2. FROM_UNIXTIME(TIME_FLOOR_WITH_FILL(column, *[, *])) ==> * 2.1 Select Item: TIME_FORMAT(TIME_FLOOR(MILLIS_TO_TIMESTAMP(column * 1000), *), 'yyyy-MM-dd HH:mm:ss') * 2.2 GroupBy or Order By Expr: TIME_FLOOR(MILLIS_TO_TIMESTAMP(column * 1000), *)] - * + * <p> * 3. TIME_FLOOR_WITH_FILL(UNIX_TIMESTAMP(column), *[, *]) ==> * 3.1 Select Item: TIMESTAMP_TO_MILLIS(TIME_FLOOR(column, *)) / 1000 * 3.2 GroupBy or Order By Expr: TIME_FLOOR(column, *) - * + * <p> * 4. TIME_FLOOR_WITH_FILL(column, *[, *]) ==> * 4.1 Select Item: TIMESTAMP_TO_MILLIS(TIME_FLOOR(MILLIS_TO_TIMESTAMP(column * 1000), *)) / 1000 * 4.2 GroupBy or Order By Expr: TIME_FLOOR(MILLIS_TO_TIMESTAMP(column * 1000), *) @@ -62,22 +63,22 @@ public class FunctionsMergeHelper { */ public static String build(String sql) throws JSQLParserException { Select select = (Select) CCJSqlParserUtil.parse(sql); - select.getSelectBody().accept(new SelectAdapter()); + select.accept(new SelectAdapter<>(), null); return select.toString(); } - private static class SelectAdapter extends SelectVisitorAdapter { + private static class SelectAdapter<T> extends SelectVisitorAdapter<T> { @SneakyThrows @Override - public void visit(PlainSelect plainSelect) { + public <S> T visit(PlainSelect plainSelect, S context) { - Map<String, String> aliasExpr = new HashMap<>(); - List<SelectItem> selectItems = plainSelect.getSelectItems(); + Map<String, String> aliasExpr = Maps.newHashMap(); + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); if (selectItems != null) { - for (SelectItem selectItem : selectItems) { + for (SelectItem<?> selectItem : selectItems) { SelectItemAdapter selectItemAdapter = new SelectItemAdapter(); - selectItem.accept(selectItemAdapter); + selectItem.accept(selectItemAdapter, null); Map<String, String> itemAliasExpr = selectItemAdapter.getAliasExpr(); if (!itemAliasExpr.isEmpty()) { aliasExpr.putAll(itemAliasExpr); @@ -86,8 +87,8 @@ public class FunctionsMergeHelper { } GroupByElement groupBy = plainSelect.getGroupBy(); - if (groupBy != null && groupBy.getGroupByExpressionList() != null && !groupBy.getGroupByExpressionList().getExpressions().isEmpty()) { - groupBy.accept(new GroupByAdapter()); + if (groupBy != null && groupBy.getGroupByExpressionList() != null && !groupBy.getGroupByExpressionList().isEmpty()) { + groupBy.accept(new GroupByAdapter(), null); } List<OrderByElement> orderByElements = plainSelect.getOrderByElements(); if (orderByElements != null) { @@ -96,31 +97,34 @@ public class FunctionsMergeHelper { Expression expression = CCJSqlParserUtil.parseExpression(aliasExpr.get(orderByElement.getExpression().toString())); orderByElement.setExpression(expression); } - orderByElement.accept(new OrderByAdapter()); + orderByElement.accept(new OrderByAdapter(), null); } } FromItem fromItem = plainSelect.getFromItem(); if (fromItem != null) { - fromItem.accept(new FromItemAdapter()); + fromItem.accept(new FromItemAdapter(), null); } + return null; + } @Override - public void visit(SetOperationList setOpList) { - for (SelectBody select : setOpList.getSelects()) { + public <S> T visit(SetOperationList setOpList, S context) { + for (Select select : setOpList.getSelects()) { if (select instanceof PlainSelect) { - select.accept(this); + select.accept(this, null); } } + return null; } } private static Function createFunction(String funName, List<Expression> params) { Function function = new Function(); function.setName(funName); - function.setParameters(new ExpressionList(params)); + function.setParameters(new ExpressionList<>(params)); return function; } @@ -130,7 +134,7 @@ public class FunctionsMergeHelper { } Function function = (Function) expression; return function.getName().equalsIgnoreCase(UNIX_TIMESTAMP) - && function.getParameters().getExpressions().size() == 1; + && function.getParameters().size() == 1; } private static boolean isTimeFloorWithFillFunction(Expression expression) { @@ -139,8 +143,8 @@ public class FunctionsMergeHelper { } Function function = (Function) expression; return TIME_FLOOR_WITH_FILL.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() >= 2 - && function.getParameters().getExpressions().size() <= 3; + && function.getParameters().size() >= 2 + && function.getParameters().size() <= 3; } private static boolean isDateTimeFloorWithFillFunction(Expression expression) { @@ -149,8 +153,8 @@ public class FunctionsMergeHelper { } Function function = (Function) expression; return DATETIME_FLOOR_WITH_FILL.equalsIgnoreCase(function.getName()) - && function.getParameters().getExpressions().size() >= 2 - && function.getParameters().getExpressions().size() <= 3; + && function.getParameters().size() >= 2 + && function.getParameters().size() <= 3; } private static boolean isFromUnixtimeFunction(Expression expression) { @@ -159,11 +163,11 @@ public class FunctionsMergeHelper { } Function function = (Function) expression; return function.getName().equalsIgnoreCase(FROM_UNIXTIME) - && function.getParameters().getExpressions().size() == 1; + && function.getParameters().size() == 1; } - private static class SelectItemAdapter extends SelectItemVisitorAdapter { + private static class SelectItemAdapter extends SelectItemVisitorAdapter<Object> { private Map<String, String> aliasExpr = new HashMap<>(); @@ -172,32 +176,32 @@ public class FunctionsMergeHelper { } @Override - public void visit(SelectExpressionItem selectExpressionItem) { - Expression expression = selectExpressionItem.getExpression(); + public Object visit(SelectItem selectItem, Object context) { + Expression expression = selectItem.getExpression(); if (!(expression instanceof Function)) { - return; + return null; } Function mainFunction = (Function) expression; if (isFromUnixtimeFunction(mainFunction)) { - Expression fromUnixtimeArg0 = mainFunction.getParameters().getExpressions().get(0); + Expression fromUnixtimeArg0 = mainFunction.getParameters().get(0); if (isTimeFloorWithFillFunction(fromUnixtimeArg0)) { Function timeFloorWithFillFun = (Function) fromUnixtimeArg0; - Expression timeFloorWithFillFunArg0 = timeFloorWithFillFun.getParameters().getExpressions().get(0); - Expression timeFloorWithFillFunArg1 = timeFloorWithFillFun.getParameters().getExpressions().get(1); - if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().getExpressions().get(0) instanceof Column) { - if (selectExpressionItem.getAlias() != null) { - aliasExpr.put(selectExpressionItem.getAlias().getName(), mainFunction.toString()); + Expression timeFloorWithFillFunArg0 = timeFloorWithFillFun.getParameters().get(0); + Expression timeFloorWithFillFunArg1 = timeFloorWithFillFun.getParameters().get(1); + if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().get(0) instanceof Column) { + if (selectItem.getAlias() != null) { + aliasExpr.put(selectItem.getAlias().getName(), mainFunction.toString()); } Function unixTimestampFun = (Function) timeFloorWithFillFunArg0; - List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().getExpressions().get(0), timeFloorWithFillFunArg1)); + List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().get(0), timeFloorWithFillFunArg1)); Function timeFloor = createFunction(TIME_FLOOR, timeFloorArgs); mainFunction.setName(TIME_FORMAT); List<Expression> timeFormatArgs = new ArrayList<>(Arrays.asList(timeFloor, new StringValue(DATE_TIME_FORMAT_PATTERN))); - mainFunction.setParameters(new ExpressionList(timeFormatArgs)); + mainFunction.setParameters(new ExpressionList<>(timeFormatArgs)); } else if (timeFloorWithFillFunArg0 instanceof Column) { - if (selectExpressionItem.getAlias() != null) { - aliasExpr.put(selectExpressionItem.getAlias().getName(), mainFunction.toString()); + if (selectItem.getAlias() != null) { + aliasExpr.put(selectItem.getAlias().getName(), mainFunction.toString()); } Multiplication multiplication = new Multiplication(); multiplication.setLeftExpression(timeFloorWithFillFunArg0); @@ -211,20 +215,20 @@ public class FunctionsMergeHelper { mainFunction.setName(TIME_FORMAT); List<Expression> timeFormatArgs = new ArrayList<>(Arrays.asList(timeFloorFun, new StringValue(DATE_TIME_FORMAT_PATTERN))); - mainFunction.setParameters(new ExpressionList(timeFormatArgs)); + mainFunction.setParameters(new ExpressionList<>(timeFormatArgs)); } } } else if (isTimeFloorWithFillFunction(mainFunction)) { - Expression timeFloorWithFillFunArg0 = mainFunction.getParameters().getExpressions().get(0); - Expression timeFloorWithFillFunArg1 = mainFunction.getParameters().getExpressions().get(1); - if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().getExpressions().get(0) instanceof Column) { + Expression timeFloorWithFillFunArg0 = mainFunction.getParameters().get(0); + Expression timeFloorWithFillFunArg1 = mainFunction.getParameters().get(1); + if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().get(0) instanceof Column) { - if (selectExpressionItem.getAlias() != null) { - aliasExpr.put(selectExpressionItem.getAlias().getName(), mainFunction.toString()); + if (selectItem.getAlias() != null) { + aliasExpr.put(selectItem.getAlias().getName(), mainFunction.toString()); } Function unixTimestampFun = (Function) timeFloorWithFillFunArg0; - List<Expression> expressions = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().getExpressions().get(0), timeFloorWithFillFunArg1)); + List<Expression> expressions = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().get(0), timeFloorWithFillFunArg1)); Function timeFloor = createFunction(TIME_FLOOR, expressions); List<Expression> timestampToMillsArgs = new ArrayList<>(Collections.singletonList(timeFloor)); @@ -233,11 +237,10 @@ public class FunctionsMergeHelper { Division division = new Division(); division.setLeftExpression(timestampToMillis); division.setRightExpression(new LongValue(1000)); - - selectExpressionItem.setExpression(division); + selectItem.setExpression(division); } else if (timeFloorWithFillFunArg0 instanceof Column) { - if (selectExpressionItem.getAlias() != null) { - aliasExpr.put(selectExpressionItem.getAlias().getName(), mainFunction.toString()); + if (selectItem.getAlias() != null) { + aliasExpr.put(selectItem.getAlias().getName(), mainFunction.toString()); } Multiplication multiplication = new Multiplication(); @@ -257,46 +260,53 @@ public class FunctionsMergeHelper { division.setLeftExpression(timestampToMills); division.setRightExpression(new LongValue(1000)); - selectExpressionItem.setExpression(division); + selectItem.setExpression(division); } } else if (isDateTimeFloorWithFillFunction(mainFunction)) { // TODO DATETIME_FLOOR_WITH_FILL function merge } + + return null; } } - private static class FromItemAdapter extends FromItemVisitorAdapter { + private static class FromItemAdapter extends FromItemVisitorAdapter<Object> { @Override - public void visit(SubSelect subSelect) { - SelectBody selectBody = subSelect.getSelectBody(); - selectBody.accept(new SelectAdapter()); + public Object visit(ParenthesedSelect parenthesedSelect, Object context) { + Select select = parenthesedSelect.getSelect(); + if (select instanceof PlainSelect) { + select.getPlainSelect().accept(new SelectAdapter<>(), null); + } else if (select instanceof SetOperationList) { + select.getSetOperationList().accept(new SelectAdapter<>(), null); + } + return null; } } - private static class GroupByAdapter implements GroupByVisitor { + private static class GroupByAdapter implements GroupByVisitor<Object> { @Override - public void visit(GroupByElement groupByElement) { - if (groupByElement.getGroupByExpressionList() == null - || groupByElement.getGroupByExpressionList().getExpressions() == null) { - return; + public Object visit(GroupByElement groupBy, Object context) { + if (groupBy.getGroupByExpressionList() == null) { + return null; } - for (Expression expression : groupByElement.getGroupByExpressionList().getExpressions()) { + + for (Object expression : groupBy.getGroupByExpressionList()) { if (!(expression instanceof Function)) { continue; } Function mainFunction = (Function) expression; - if (isFromUnixtimeFunction(expression)) { - Expression fromUnixtimeArg0 = mainFunction.getParameters().getExpressions().get(0); + if (isFromUnixtimeFunction(mainFunction)) { + Expression fromUnixtimeArg0 = mainFunction.getParameters().get(0); if (isTimeFloorWithFillFunction(fromUnixtimeArg0)) { Function timeFloorWithFillFun = (Function) fromUnixtimeArg0; - Expression timeFloorWithFillFunArg0 = timeFloorWithFillFun.getParameters().getExpressions().get(0); - Expression timeFloorWithFillFunArg1 = timeFloorWithFillFun.getParameters().getExpressions().get(1); - if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().getExpressions().get(0) instanceof Column) { + Expression timeFloorWithFillFunArg0 = timeFloorWithFillFun.getParameters().get(0); + Expression timeFloorWithFillFunArg1 = timeFloorWithFillFun.getParameters().get(1); + if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().get(0) instanceof Column) { Function unixTimestampFun = (Function) timeFloorWithFillFunArg0; mainFunction.setName(TIME_FLOOR); - List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().getExpressions().get(0), timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().get(0), timeFloorWithFillFunArg1)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } else if (timeFloorWithFillFunArg0 instanceof Column) { Multiplication multiplication = new Multiplication(); multiplication.setLeftExpression(timeFloorWithFillFunArg0); @@ -307,17 +317,17 @@ public class FunctionsMergeHelper { mainFunction.setName(TIME_FLOOR); ArrayList<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(millsToTimestamp, timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } } } else if (isTimeFloorWithFillFunction(mainFunction)) { - Expression timeFloorWithFillFunArg0 = mainFunction.getParameters().getExpressions().get(0); - Expression timeFloorWithFillFunArg1 = mainFunction.getParameters().getExpressions().get(1); - if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().getExpressions().get(0) instanceof Column) { + Expression timeFloorWithFillFunArg0 = mainFunction.getParameters().get(0); + Expression timeFloorWithFillFunArg1 = mainFunction.getParameters().get(1); + if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().get(0) instanceof Column) { Function unixTimestampFun = (Function) timeFloorWithFillFunArg0; mainFunction.setName(TIME_FLOOR); - List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().getExpressions().get(0), timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().get(0), timeFloorWithFillFunArg1)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } else if (timeFloorWithFillFunArg0 instanceof Column) { Multiplication multiplication = new Multiplication(); multiplication.setLeftExpression(timeFloorWithFillFunArg0); @@ -328,34 +338,35 @@ public class FunctionsMergeHelper { mainFunction.setName(TIME_FLOOR); List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(millsToTimestamp, timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } } } + return null; } } - private static class OrderByAdapter implements OrderByVisitor { + private static class OrderByAdapter implements OrderByVisitor<Object> { @Override - public void visit(OrderByElement orderBy) { + public Object visit(OrderByElement orderBy, Object context) { if (orderBy.getExpression() == null) { - return; + return null; } if (!(orderBy.getExpression() instanceof Function)) { - return; + return null; } Function mainFunction = (Function) orderBy.getExpression(); if (isFromUnixtimeFunction(mainFunction)) { - Expression fromUnixtimeArg0 = mainFunction.getParameters().getExpressions().get(0); + Expression fromUnixtimeArg0 = mainFunction.getParameters().get(0); if (isTimeFloorWithFillFunction(fromUnixtimeArg0)) { Function timeFloorWithFillFun = (Function) fromUnixtimeArg0; - Expression timeFloorWithFillFunArg0 = timeFloorWithFillFun.getParameters().getExpressions().get(0); - Expression timeFloorWithFillFunArg1 = timeFloorWithFillFun.getParameters().getExpressions().get(1); - if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().getExpressions().get(0) instanceof Column) { + Expression timeFloorWithFillFunArg0 = timeFloorWithFillFun.getParameters().get(0); + Expression timeFloorWithFillFunArg1 = timeFloorWithFillFun.getParameters().get(1); + if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().get(0) instanceof Column) { Function unixTimestampFun = (Function) timeFloorWithFillFunArg0; mainFunction.setName(TIME_FLOOR); - List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().getExpressions().get(0), timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().get(0), timeFloorWithFillFunArg1)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } else if (timeFloorWithFillFunArg0 instanceof Column) { Multiplication multiplication = new Multiplication(); multiplication.setLeftExpression(timeFloorWithFillFunArg0); @@ -366,17 +377,17 @@ public class FunctionsMergeHelper { mainFunction.setName(TIME_FLOOR); ArrayList<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(millsToTimestamp, timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } } } else if (isTimeFloorWithFillFunction(mainFunction)) { - Expression timeFloorWithFillFunArg0 = mainFunction.getParameters().getExpressions().get(0); - Expression timeFloorWithFillFunArg1 = mainFunction.getParameters().getExpressions().get(1); - if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().getExpressions().get(0) instanceof Column) { + Expression timeFloorWithFillFunArg0 = mainFunction.getParameters().get(0); + Expression timeFloorWithFillFunArg1 = mainFunction.getParameters().get(1); + if (isUnixTimestampFunction(timeFloorWithFillFunArg0) && ((Function) timeFloorWithFillFunArg0).getParameters().get(0) instanceof Column) { Function unixTimestampFun = (Function) timeFloorWithFillFunArg0; mainFunction.setName(TIME_FLOOR); - List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().getExpressions().get(0), timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(unixTimestampFun.getParameters().get(0), timeFloorWithFillFunArg1)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } else if (timeFloorWithFillFunArg0 instanceof Column) { Multiplication multiplication = new Multiplication(); multiplication.setLeftExpression(timeFloorWithFillFunArg0); @@ -387,9 +398,10 @@ public class FunctionsMergeHelper { mainFunction.setName(TIME_FLOOR); List<Expression> timeFloorArgs = new ArrayList<>(Arrays.asList(millsToTimestamp, timeFloorWithFillFunArg1)); - mainFunction.setParameters(new ExpressionList(timeFloorArgs)); + mainFunction.setParameters(new ExpressionList<>(timeFloorArgs)); } } + return null; } } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/QueryTypeHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/QueryTypeHelper.java index 0adfba40..b077e441 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/QueryTypeHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/QueryTypeHelper.java @@ -6,9 +6,9 @@ import com.mesalab.qgw.model.basic.SelectStatement; import com.mesalab.qgw.model.basic.udf.TIME_FLOOR_WITH_FILL; import com.mesalab.qgw.model.basic.udf.DATETIME_FLOOR_WITH_FILL; import com.mesalab.qgw.model.basic.udf.UDF; +import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Function; import net.sf.jsqlparser.statement.select.OrderByElement; -import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SelectItem; import java.util.List; @@ -43,18 +43,16 @@ public class QueryTypeHelper { return ExampleDataHelper.QUERY_TYPE_GROUP_BY; } - List<SelectItem> selectItems = dbSelectStatement.getSelectItems(); + List<SelectItem<?>> selectItems = dbSelectStatement.getSelectItems(); if (selectItems != null && !selectItems.isEmpty()) { - for (SelectItem selectItem : selectItems) { - if (selectItem instanceof SelectExpressionItem) { - SelectExpressionItem selectExpressionItem = ((SelectExpressionItem) selectItem); - if (selectExpressionItem.getExpression() instanceof Function) { - Function function = (Function) selectExpressionItem.getExpression(); - if (SQLFunctionUtil.pAggregateFunStandard.matcher(function.toString()).find() - || ClickHouseDialect.pAggregateFunSpecificOfCK.matcher(function.toString()).find() - || DruidDialect.pAggregateFunSpecificOfDruid.matcher(function.toString()).find()) { - return ExampleDataHelper.QUERY_TYPE_AGG_STATISTICS; - } + for (SelectItem<?> selectItem : selectItems) { + Expression expression = selectItem.getExpression(); + if (expression instanceof Function) { + Function function = (Function) expression; + if (SQLFunctionUtil.pAggregateFunStandard.matcher(function.toString()).find() + || ClickHouseDialect.pAggregateFunSpecificOfCK.matcher(function.toString()).find() + || DruidDialect.pAggregateFunSpecificOfDruid.matcher(function.toString()).find()) { + return ExampleDataHelper.QUERY_TYPE_AGG_STATISTICS; } } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/SQLFunctionUtil.java b/src/main/java/com/mesalab/common/utils/sqlparser/SQLFunctionUtil.java index 5dc68cbe..4265f960 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/SQLFunctionUtil.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/SQLFunctionUtil.java @@ -756,8 +756,8 @@ public class SQLFunctionUtil { if (expression instanceof CastExpression) { CastExpression castExpression = (CastExpression) expression; if (DBEngineType.CLICKHOUSE.getValue().equals(dbType)) { - String dataType = castExpression.getType().getDataType(); - castExpression.getType().setDataType("Nullable(" + dataType + ")"); + String dataType = castExpression.getColDataType().getDataType(); + castExpression.getColDataType().setDataType("Nullable(" + dataType + ")"); } replaceValue = String.valueOf(castExpression).replace("(", "#[").replace(")", "#]"); } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/SQLHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/SQLHelper.java index 7e8fe1b8..4583444b 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/SQLHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/SQLHelper.java @@ -13,6 +13,7 @@ import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Function; import net.sf.jsqlparser.expression.LongValue; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.ExplainStatement; @@ -180,9 +181,8 @@ public class SQLHelper { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select select = (Select) statement; - SelectBody selectBody = select.getSelectBody(); - if (selectBody instanceof PlainSelect) { - PlainSelect plainSelect = (PlainSelect) selectBody; + if (select instanceof PlainSelect) { + PlainSelect plainSelect = select.getPlainSelect(); Limit limit = plainSelect.getLimit(); if (limit != null) { Expression rowCount = limit.getRowCount(); @@ -215,14 +215,13 @@ public class SQLHelper { Select selectStatement = null; if (statement instanceof Select) { selectStatement = (Select) statement; - SelectBody selectBody = selectStatement.getSelectBody(); - if (selectBody instanceof PlainSelect) { - PlainSelect plainSelect = (PlainSelect) selectBody; - List<SelectItem> selectItems = plainSelect.getSelectItems(); + if (selectStatement instanceof PlainSelect) { + PlainSelect plainSelect = selectStatement.getPlainSelect(); + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); for (SelectItem selectItem : selectItems) { - if ((selectItem instanceof SelectExpressionItem) && (((SelectExpressionItem) selectItem).getExpression()) instanceof Function) { - Expression expression = ((SelectExpressionItem) selectItem).getExpression(); - List<Expression> expressions = getExpressions(functionName, expression); + if (selectItem.getExpression() instanceof Function) { + Expression expression = selectItem.getExpression(); + ExpressionList expressions = getExpressions(functionName, expression); if (!expressions.isEmpty()) { return expressions; } @@ -244,16 +243,16 @@ public class SQLHelper { return Lists.newArrayList(); } - private static List<Expression> getExpressions(String functionName, Expression expression) { + private static ExpressionList<?> getExpressions(String functionName, Expression expression) { if (expression instanceof Function) { Function function = (Function) expression; if (((Function) expression).getName().equalsIgnoreCase(functionName)) { - return function.getParameters().getExpressions(); + return function.getParameters(); } else { if (StringUtil.isNotEmpty(function.getParameters())) { - List<Expression> expressions = function.getParameters().getExpressions(); + ExpressionList<?> expressions = function.getParameters(); for (Expression expression1 : expressions) { - List<Expression> expressions1 = getExpressions(functionName, expression1); + ExpressionList expressions1 = getExpressions(functionName, expression1); if (!expressions1.isEmpty()) { return expressions1; } @@ -261,7 +260,7 @@ public class SQLHelper { } } } - return Lists.newArrayList(); + return new ExpressionList<>(); } /** @@ -296,7 +295,7 @@ public class SQLHelper { if (fromItem instanceof Table) { return plainSelect; } - SubSelect subSelect = (SubSelect) fromItem; - return (PlainSelect) subSelect.getSelectBody(); + ParenthesedSelect subSelect = (ParenthesedSelect) fromItem; + return subSelect.getPlainSelect(); } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/SQLSyntaxParserUtil.java b/src/main/java/com/mesalab/common/utils/sqlparser/SQLSyntaxParserUtil.java index 7c0a9642..50053786 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/SQLSyntaxParserUtil.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/SQLSyntaxParserUtil.java @@ -6,10 +6,8 @@ import com.geedgenetworks.utils.StringUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.mesalab.common.enums.HttpStatusCodeEnum; -import com.mesalab.common.utils.SpringContextUtil; import com.mesalab.qgw.exception.QGWBusinessException; import com.mesalab.common.exception.CommonErrorCode; -import com.mesalab.qgw.service.SQLSyncQueryService; import lombok.Data; import lombok.NoArgsConstructor; import net.sf.jsqlparser.JSQLParserException; @@ -19,7 +17,7 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.relational.Between; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.InExpression; -import net.sf.jsqlparser.expression.operators.relational.ItemsList; +import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; @@ -46,7 +44,7 @@ public class SQLSyntaxParserUtil { } catch (RuntimeException | JSQLParserException e) { log.error("syntax_parse: sql-" + sql + ", error: ", e); throw new QGWBusinessException(HttpStatusCodeEnum.SERVER_ERROR.getCode(), CommonErrorCode.BAD_REQUEST_SQL_SYNTAX_PARSE_EXCEPTION.getCode(), - String.format(CommonErrorCode.BAD_REQUEST_SQL_SYNTAX_PARSE_EXCEPTION.getMessage(),e.getMessage())); + String.format(CommonErrorCode.BAD_REQUEST_SQL_SYNTAX_PARSE_EXCEPTION.getMessage(), e.getMessage())); } return resultList; } @@ -55,11 +53,12 @@ public class SQLSyntaxParserUtil { Statement parse = null; parse = CCJSqlParserUtil.parse(sql); SQLStructure sqlStructure = new SQLStructure(); - if (!(parse instanceof Select)) return; + if (!(parse instanceof Select)) { + return; + } Select select = (Select) parse; - SelectBody selectBody = select.getSelectBody(); - if (selectBody instanceof PlainSelect) { - PlainSelect plainSelect = (PlainSelect) selectBody; + if (select instanceof PlainSelect) { + PlainSelect plainSelect = (PlainSelect) select; sqlStructure.setSelect(getSelectItems(plainSelect.getSelectItems())); sqlStructure.setFrom(getFromItems(plainSelect.getFromItem())); sqlStructure.setWhere(getWhereItems(plainSelect.getWhere())); @@ -68,12 +67,14 @@ public class SQLSyntaxParserUtil { sqlStructure.setOrderBy(getOrderBy(plainSelect.getOrderByElements())); sqlStructure.setLimit(getLimit(plainSelect.getLimit(), plainSelect.getOffset())); result.add(sqlStructure); - } else if (selectBody instanceof SetOperationList) { - SetOperationList setOperationList = (SetOperationList) selectBody; - List<SelectBody> selects = setOperationList.getSelects(); + } else if (select instanceof SetOperationList) { + SetOperationList setOperationList = select.getSetOperationList(); + List<Select> selects = setOperationList.getSelects(); for (int i = 0; i < selects.size(); i++) { parseSQL(selects.get(i).toString(), result); - if (i + 1 >= selects.size()) return; + if (i + 1 >= selects.size()) { + return; + } Map<String, Object> conMap = Maps.newHashMap(); conMap.put(CONNECTOR, setOperationList.getOperations().get(i).toString()); result.add(conMap); @@ -145,8 +146,8 @@ public class SQLSyntaxParserUtil { Table table = (Table) fromItem; itemMap.put(NODE, TABLE); itemMap.put(VALUE_L, table.toString()); - } else if (fromItem instanceof SubSelect) { - SubSelect subSelect = (SubSelect) fromItem; + } else if (fromItem instanceof ParenthesedSelect) { + ParenthesedSelect subSelect = (ParenthesedSelect) fromItem; itemMap.put(NODE, SUB_SELECT); itemMap.put(VALUE_L, subSelect.toString()); } else { @@ -156,30 +157,29 @@ public class SQLSyntaxParserUtil { return resultList; } - private static List<Map<String, Object>> getSelectItems(List<SelectItem> selectItemList) { + private static List<Map<String, Object>> getSelectItems(List<SelectItem<?>> selectItemList) { List<Map<String, Object>> resultItems = Lists.newArrayList(); for (SelectItem item : selectItemList) { Map<String, Object> itemMap = Maps.newHashMap(); Map<String, Object> exp = Maps.newHashMap(); - if (item instanceof AllTableColumns) { - AllTableColumns allTableColumns = (AllTableColumns) item; + Expression itemExpr = item.getExpression(); + if (itemExpr instanceof AllTableColumns) { + AllTableColumns allTableColumns = (AllTableColumns) itemExpr; itemMap.put(ITEM, allTableColumns.toString()); exp.put(NODE, COLUMN); exp.put(NAME, allTableColumns.toString()); itemMap.put(EXPRESSION, exp); - } else if (item instanceof AllColumns) { - AllColumns allColumns = (AllColumns) item; + } else if (itemExpr instanceof AllColumns) { + AllColumns allColumns = (AllColumns) itemExpr; itemMap.put(ITEM, allColumns.toString()); exp.put(NODE, COLUMN); exp.put(NAME, allColumns.toString()); itemMap.put(EXPRESSION, exp); - } else if (item instanceof SelectExpressionItem) { - SelectExpressionItem selectExpressionItem = (SelectExpressionItem) item; - Expression expression = selectExpressionItem.getExpression(); + } else if (itemExpr instanceof SelectItem) { itemMap.put(ITEM, item.toString()); - itemMap.put(EXPRESSION, getExpression(expression)); - Optional<Alias> alias = Optional.ofNullable(selectExpressionItem.getAlias()); + itemMap.put(EXPRESSION, getExpression(itemExpr)); + Optional<Alias> alias = Optional.ofNullable(item.getAlias()); alias.ifPresent(o -> { exp.put(NAME, o.getName()); exp.put(USEAS, o.isUseAs()); @@ -212,7 +212,7 @@ public class SQLSyntaxParserUtil { resultMap.put(NODE, FUNCTION); resultMap.put(NAME, function.getName()); Optional.ofNullable(function.getParameters()).ifPresent(o -> { - Map<String, Object> parameters = getParameters(function.getParameters().getExpressions()); + Map<String, Object> parameters = getParameters(function.getParameters()); resultMap.put(PARAMETERS, parameters); }); } else if (expression instanceof AndExpression) { @@ -240,16 +240,12 @@ public class SQLSyntaxParserUtil { resultMap.put(LEFT_EXPRESSION, getExpression(leftExpression)); resultMap.put(RIGHT_EXPRESSION, getExpression(rightExpression)); resultMap.put("operator", stringExpression); - } else if (expression instanceof Parenthesis) { - Parenthesis parenthesis = (Parenthesis) expression; - return getExpression(parenthesis.getExpression()); + } else if (expression instanceof ParenthesedExpressionList) { + return getExpression(expression); } else if (expression instanceof InExpression) { InExpression inExpression = (InExpression) expression; resultMap.put(NODE, IN_EXPRESSION); resultMap.put(LEFT_EXPRESSION, getExpression(inExpression.getLeftExpression())); - if (StringUtil.isNotEmpty(inExpression.getRightItemsList())) { - resultMap.put(RIGHT_EXPRESSION, getItemsList(inExpression.getRightItemsList())); - } if (StringUtil.isNotEmpty(inExpression.getRightExpression())) { resultMap.put(RIGHT_EXPRESSION, getExpression(inExpression.getRightExpression())); } @@ -261,23 +257,7 @@ public class SQLSyntaxParserUtil { return resultMap; } - private static Map getItemsList(ItemsList itemsList) { - Map<String, Object> map = Maps.newHashMap(); - if (itemsList instanceof SubSelect) { - map.put(NODE, SUB_SELECT); - map.put(VALUE_L, itemsList.toString()); - } else if (itemsList instanceof ExpressionList) { - ExpressionList expressionList = (ExpressionList) itemsList; - List<Expression> expressions = expressionList.getExpressions(); - Map<String, Object> parameters = getParameters(expressions); - map.put(PARAMETERS, parameters); - } else { - throw new RuntimeException("Parse ItemsList Error, Not Support This."); - } - return map; - } - - private static Map<String, Object> getParameters(List<Expression> parameters) { + private static Map<String, Object> getParameters(ExpressionList<?> parameters) { List<Map<String, Object>> list = Lists.newArrayList(); for (Expression parameter : parameters) { list.add(getExpression(parameter)); diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/SQLVisitorUtil.java b/src/main/java/com/mesalab/common/utils/sqlparser/SQLVisitorUtil.java index acf40a6c..bb9b79e1 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/SQLVisitorUtil.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/SQLVisitorUtil.java @@ -30,19 +30,20 @@ public class SQLVisitorUtil { public static SelectVisitor getVisitorOfEscapeMetadataWithDoubleQuote() { ExpressionDeParser expressionDeParser = new ExpressionDeParser() { @Override - public void visit(Column column) { + public StringBuilder visit(Column column, Object context) { Table table = column.getTable(); if (!StrUtil.isBlankIfStr(table)) { table.setName(addDoubleQuote(table.getName())); } String columnName = column.getColumnName(); column.setColumnName(addDoubleQuote(columnName)); + return null; } }; return new SelectDeParser(expressionDeParser, new StringBuilder()) { @Override - public void visit(Table table) { + public StringBuilder visit(Table table, Object context) { String name = table.getName(); if (!StrUtil.isBlankIfStr(name)) { table.setName(addDoubleQuote(name)); @@ -52,23 +53,7 @@ public class SQLVisitorUtil { if (!StrUtil.isBlankIfStr(alias)) { alias.setName(addDoubleQuote(alias.getName())); } - } - - @Override - public void visit(AllTableColumns allTableColumns) { - Table table = allTableColumns.getTable(); - if (!StrUtil.isBlankIfStr(table)) { - table.setName(addDoubleQuote(table.getName())); - } - } - - @Override - public void visit(SelectExpressionItem selectExpressionItem) { - selectExpressionItem.getExpression().accept(expressionDeParser); - Alias alias = selectExpressionItem.getAlias(); - if (!StrUtil.isBlankIfStr(alias) && !StrUtil.isBlank(alias.getName())) { - alias.setName(addDoubleQuote(alias.getName())); - } + return null; } }; } @@ -84,8 +69,9 @@ public class SQLVisitorUtil { public static ExpressionVisitor getVisitorOfRenameColumn(String newColumnName) { return new ExpressionVisitorAdapter() { @Override - public void visit(Column column) { + public Object visit(Column column, Object context) { column.setColumnName(newColumnName); + return null; } }; } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelper.java index 1e5a3ff5..a6c541e1 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelper.java @@ -5,10 +5,10 @@ import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitorAdapter; import net.sf.jsqlparser.expression.LongValue; -import net.sf.jsqlparser.expression.Parenthesis; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; +import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.*; @@ -57,50 +57,54 @@ public class SampleSQLHelper { */ public String build() throws JSQLParserException { Select select = (Select) CCJSqlParserUtil.parse(originalSQL); - select.getSelectBody().accept(new SelectAdapter()); + select.accept(new SelectAdapter(), null); return select.toString(); } - private class FromItemAdapter extends FromItemVisitorAdapter { + private class FromItemAdapter extends FromItemVisitorAdapter<Object> { @Override - public void visit(SubSelect subSelect) { - SelectBody selectBody = subSelect.getSelectBody(); - selectBody.accept(new SelectAdapter()); + public Object visit(ParenthesedSelect parenthesedSelect, Object context) { + Select select = parenthesedSelect.getSelect(); + select.accept(new SelectAdapter(), null); + return null; } } - private class ExpressionAdapter extends ExpressionVisitorAdapter { + private class ExpressionAdapter extends ExpressionVisitorAdapter<Object> { @Override - public void visit(SubSelect subSelect) { - SelectBody selectBody = subSelect.getSelectBody(); - selectBody.accept(new SelectAdapter()); + public Object visit(ParenthesedSelect parenthesedSelect, Object context) { + Select select = parenthesedSelect.getSelect(); + select.accept(new SelectAdapter(), null); + return null; } } - private class SelectItemAdapter extends SelectItemVisitorAdapter { + private class SelectItemAdapter extends SelectItemVisitorAdapter<Object> { @Override - public void visit(SelectExpressionItem item) { - item.getExpression().accept(new ExpressionAdapter()); + public Object visit(SelectItem selectItem, Object context) { + Expression expression = selectItem.getExpression(); + expression.accept(new ExpressionAdapter(), null); + return null; } } - private class SelectAdapter extends SelectVisitorAdapter { + private class SelectAdapter extends SelectVisitorAdapter<Object> { @SneakyThrows @Override - public void visit(PlainSelect plainSelect) { - List<SelectItem> selectItems = plainSelect.getSelectItems(); + public Object visit(PlainSelect plainSelect, Object context) { + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); if (selectItems != null) { - for (SelectItem selectItem : selectItems) { - selectItem.accept(new SelectItemAdapter()); + for (SelectItem<?> selectItem : selectItems) { + selectItem.accept(new SelectItemAdapter(), null); } } FromItem fromItem = plainSelect.getFromItem(); if (fromItem != null) { - fromItem.accept(new FromItemAdapter()); + fromItem.accept(new FromItemAdapter(), null); } if ((fromItem instanceof Table) && filterExpr != null) { @@ -113,10 +117,12 @@ public class SampleSQLHelper { where = plainSelect.getWhere(); } AndExpression andExpression = new AndExpression(); - Parenthesis parenthesisLeft = new Parenthesis(); - parenthesisLeft.setExpression(where instanceof Parenthesis ? ((Parenthesis) where).getExpression() : where); - Parenthesis parenthesisRight = new Parenthesis(); - parenthesisRight.setExpression(expression); + + ParenthesedExpressionList<Expression> parenthesisLeft = new ParenthesedExpressionList<>(); + parenthesisLeft.add(where); + ParenthesedExpressionList<Expression> parenthesisRight = new ParenthesedExpressionList<>(); + parenthesisRight.add(expression); + andExpression.setLeftExpression(parenthesisLeft); andExpression.setRightExpression(parenthesisRight); plainSelect.setWhere(andExpression); @@ -131,7 +137,7 @@ public class SampleSQLHelper { OrExpression orExpression = buildOrExpression(having); plainSelect.setHaving(orExpression); } - having.accept(new ExpressionAdapter()); + having.accept(new ExpressionAdapter(), null); } Limit limit = plainSelect.getLimit(); @@ -140,15 +146,17 @@ public class SampleSQLHelper { limitObj.setRowCount(new LongValue(maxSize)); plainSelect.setLimit(limitObj); } + return null; } @Override - public void visit(SetOperationList setOpList) { - for (SelectBody select : setOpList.getSelects()) { + public Object visit(SetOperationList setOpList, Object context) { + for (Select select : setOpList.getSelects()) { if (select instanceof PlainSelect) { - select.accept(this); + select.accept(this, null); } } + return null; } private OrExpression buildOrExpression(Expression where) { diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelperOfDataset.java b/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelperOfDataset.java index 14b6a719..61a0341c 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelperOfDataset.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/SampleSQLHelperOfDataset.java @@ -56,60 +56,66 @@ public class SampleSQLHelperOfDataset { */ public String build() throws JSQLParserException { Select select = (Select) CCJSqlParserUtil.parse(originalSQL); - select.getSelectBody().accept(new SelectAdapter()); + select.getSelectBody().accept(new SelectAdapter(), null); return select.toString(); } - private class FromItemAdapter extends FromItemVisitorAdapter { + private class FromItemAdapter extends FromItemVisitorAdapter<Object> { @Override - public void visit(Table table) { + public Object visit(Table table, Object context) { if (StrUtil.isEmptyIfStr(templateSQL)) { - return; + return null; } if (table.getAlias() == null) { table.setAlias(new Alias(table.getName(), true)); } table.setName(StrUtil.format("(" + templateSQL + ")", table.getFullyQualifiedName())); table.setSchemaName(null); + return null; } + @Override - public void visit(SubSelect subSelect) { - SelectBody selectBody = subSelect.getSelectBody(); - selectBody.accept(new SelectAdapter()); + public Object visit(ParenthesedSelect parenthesedSelect, Object context) { + Select select = parenthesedSelect.getSelect(); + select.accept(new SelectAdapter(), null); + return null; } } - private class ExpressionAdapter extends ExpressionVisitorAdapter { + private class ExpressionAdapter extends ExpressionVisitorAdapter<Object> { @Override - public void visit(SubSelect subSelect) { - SelectBody selectBody = subSelect.getSelectBody(); - selectBody.accept(new SelectAdapter()); + public Object visit(ParenthesedSelect parenthesedSelect, Object context) { + Select select = parenthesedSelect.getSelect(); + select.accept(new SelectAdapter(), null); + return null; } } - private class SelectItemAdapter extends SelectItemVisitorAdapter { + private class SelectItemAdapter extends SelectItemVisitorAdapter<Object> { @Override - public void visit(SelectExpressionItem item) { - item.getExpression().accept(new ExpressionAdapter()); + public Object visit(SelectItem selectItem, Object context) { + Expression expression = selectItem.getExpression(); + expression.accept(new ExpressionAdapter(), null); + return null; } } - private class SelectAdapter extends SelectVisitorAdapter { + private class SelectAdapter extends SelectVisitorAdapter<Object> { @Override - public void visit(PlainSelect plainSelect) { - List<SelectItem> selectItems = plainSelect.getSelectItems(); + public Object visit(PlainSelect plainSelect, Object context) { + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); if (selectItems != null) { - for (SelectItem selectItem : selectItems) { - selectItem.accept(new SelectItemAdapter()); + for (SelectItem<?> selectItem : selectItems) { + selectItem.accept(new SelectItemAdapter(), null); } } FromItem fromItem = plainSelect.getFromItem(); if (fromItem != null) { - fromItem.accept(new FromItemAdapter()); + fromItem.accept(new FromItemAdapter(), null); } Expression where = plainSelect.getWhere(); @@ -119,7 +125,7 @@ public class SampleSQLHelperOfDataset { plainSelect.setWhere(orExpression); } - where.accept(new ExpressionAdapter()); + where.accept(new ExpressionAdapter(), null); } Expression having = plainSelect.getHaving(); @@ -128,17 +134,19 @@ public class SampleSQLHelperOfDataset { OrExpression orExpression = buildOrExpression(having); plainSelect.setHaving(orExpression); } - having.accept(new ExpressionAdapter()); + having.accept(new ExpressionAdapter(), null); } + return null; } @Override - public void visit(SetOperationList setOpList) { - for (SelectBody select : setOpList.getSelects()) { + public Object visit(SetOperationList setOpList, Object context) { + for (Select select : setOpList.getSelects()) { if (select instanceof PlainSelect) { - select.accept(this); + select.accept(this, null); } } + return null; } private OrExpression buildOrExpression(Expression where) { diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/SelectItemHelper.java b/src/main/java/com/mesalab/common/utils/sqlparser/SelectItemHelper.java index 09b236d5..43178cab 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/SelectItemHelper.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/SelectItemHelper.java @@ -7,8 +7,9 @@ import lombok.SneakyThrows; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Function; -import net.sf.jsqlparser.expression.Parenthesis; import net.sf.jsqlparser.expression.RowConstructor; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.*; @@ -52,11 +53,11 @@ public class SelectItemHelper { public static Map<String, AliasObject> getSelectItem(String sql) throws JSQLParserException { Select select = (Select) CCJSqlParserUtil.parse(sql); SelectAdapter selectAdapter = new SelectAdapter(); - select.getSelectBody().accept(selectAdapter); + select.accept(selectAdapter, null); return selectAdapter.getAliasObjects(); } - private static class SelectAdapter extends SelectVisitorAdapter { + private static class SelectAdapter extends SelectVisitorAdapter<Object> { private final Map<String, AliasObject> aliasObjects = Maps.newHashMap(); @@ -66,33 +67,35 @@ public class SelectItemHelper { @SneakyThrows @Override - public void visit(PlainSelect plainSelect) { - List<SelectItem> selectItems = plainSelect.getSelectItems(); + public Object visit(PlainSelect plainSelect, Object context) { + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); if (selectItems == null) { - return; + return null; } for (int i = 0; i < selectItems.size(); i++) { - SelectItem selectItem = selectItems.get(i); + SelectItem<?> selectItem = selectItems.get(i); SelectItemAdapter selectItemAdapter = new SelectItemAdapter(); - selectItem.accept(selectItemAdapter); + selectItem.accept(selectItemAdapter, null); AliasObject aliasExpr = selectItemAdapter.getAliasExpr(); if (aliasExpr != null) { aliasExpr.setIndex(i); this.aliasObjects.put(aliasExpr.getName(), aliasExpr); } } + return null; } @Override - public void visit(SetOperationList setOpList) { - SelectBody selectBody = setOpList.getSelects().get(0); - if (selectBody instanceof PlainSelect) { - selectBody.accept(this); + public Object visit(SetOperationList setOpList, Object context) { + Select select = setOpList.getSelects().get(0); + if (select instanceof PlainSelect) { + select.accept(this, null); } + return null; } } - private static class SelectItemAdapter extends SelectItemVisitorAdapter { + private static class SelectItemAdapter extends SelectItemVisitorAdapter<Object> { private AliasObject aliasExpr = new AliasObject(); @@ -101,7 +104,7 @@ public class SelectItemHelper { } @Override - public void visit(SelectExpressionItem selectExpressionItem) { + public Object visit(SelectItem selectExpressionItem, Object context) { Expression expression = selectExpressionItem.getExpression(); String name = selectExpressionItem.getAlias() != null ? selectExpressionItem.getAlias().getName() : selectExpressionItem.toString(); name = SQLHelper.removeQuotesAndBackticks(name); @@ -111,14 +114,14 @@ public class SelectItemHelper { aliasColumn.setName(name); aliasColumn.setFieldName(column.getColumnName()); this.aliasExpr = aliasColumn; - return; + return null; } else if (expression instanceof Function) { Function function = (Function) expression; String functionName = function.getName().toUpperCase(); if (SQLFunctionUtil.GROUP_UNIQ_ARRAY.equalsIgnoreCase(functionName) && function.getParameters() != null - && function.getParameters().getExpressions() != null) { - List<Expression> paramExpressions = function.getParameters().getExpressions(); + && !function.getParameters().isEmpty()) { + ExpressionList<?> paramExpressions = function.getParameters(); Expression expr1 = paramExpressions.get(0); if (expr1 instanceof Column) { Column column = (Column) expr1; @@ -127,36 +130,37 @@ public class SelectItemHelper { aliasColumn.setFieldName(column.getColumnName()); aliasColumn.setArray(true); this.aliasExpr = aliasColumn; - return; - } else if ((expr1 instanceof Parenthesis) && ((Parenthesis) expr1).getExpression() instanceof Column) { - Column column = (Column) ((Parenthesis) expr1).getExpression(); + return null; + } else if ((expr1 instanceof ParenthesedExpressionList) && ((ParenthesedExpressionList) expr1).get(0) instanceof Column) { + Column column = (Column) ((ParenthesedExpressionList) expr1).get(0); AliasColumn aliasColumn = new AliasColumn(); aliasColumn.setName(name); aliasColumn.setFieldName(column.getColumnName()); aliasColumn.setArray(true); this.aliasExpr = aliasColumn; - return; - } else if (expr1 instanceof RowConstructor + return null; + }/* else if (expr1 instanceof RowConstructor && ((RowConstructor) expr1).getExprList() != null && ((RowConstructor) expr1).getExprList().getExpressions().get(0) instanceof Column) { AliasColumn aliasColumn = new AliasColumn(); aliasColumn.setName(name); aliasColumn.setArray(true); this.aliasExpr = aliasColumn; - return; - } + return null; + }*/ } if (FUNCTION_DATE_TYPE_MAPPING.containsKey(functionName)) { AliasFunExpr aliasFunExpr = new AliasFunExpr(); aliasFunExpr.setName(name); aliasFunExpr.setDateType(FUNCTION_DATE_TYPE_MAPPING.get(functionName)); this.aliasExpr = aliasFunExpr; - return; + return null; } AliasObject aliasObject = new AliasObject(); aliasObject.setName(name); this.aliasExpr = aliasObject; } + return null; } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/TimeBasedShardingUtil.java b/src/main/java/com/mesalab/common/utils/sqlparser/TimeBasedShardingUtil.java index 85de2192..6d920426 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/TimeBasedShardingUtil.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/TimeBasedShardingUtil.java @@ -4,11 +4,11 @@ import lombok.SneakyThrows; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitorAdapter; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.*; -import net.sf.jsqlparser.statement.values.ValuesStatement; import java.util.List; @@ -43,7 +43,11 @@ public class TimeBasedShardingUtil { } Select select = (Select) parse; SelectAdapter selectAdapter = new SelectAdapter(); - select.getSelectBody().accept(selectAdapter); + if (select instanceof PlainSelect) { + select.getPlainSelect().accept(selectAdapter, null); + } else if (select instanceof SetOperationList) { + select.getSetOperationList().accept(selectAdapter, null); + } if (!selectAdapter.isBasic) { return false; } @@ -58,22 +62,19 @@ public class TimeBasedShardingUtil { } - private static class SelectAdapter extends SelectVisitorAdapter { + private static class SelectAdapter extends SelectVisitorAdapter<Object> { private boolean isBasic = true; @SneakyThrows @Override - public void visit(PlainSelect plainSelect) { - List<SelectItem> selectItems = plainSelect.getSelectItems(); + public Object visit(PlainSelect plainSelect, Object context) { + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); if (selectItems != null) { - for (SelectItem selectItem : selectItems) { - if (selectItem instanceof SelectExpressionItem) { - SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem; - Expression expression = selectExpressionItem.getExpression(); - if (expression instanceof SubSelect) { - isBasic = false; - return; - } + for (SelectItem<?> selectItem : selectItems) { + Expression expression = selectItem.getExpression(); + if (expression instanceof ParenthesedSelect) { + isBasic = false; + return null; } } } @@ -81,37 +82,37 @@ public class TimeBasedShardingUtil { FromItem fromItem = plainSelect.getFromItem(); if (!(fromItem instanceof Table)) { isBasic = false; - return; + return null; } List<Join> joins = plainSelect.getJoins(); if (joins != null && !joins.isEmpty()) { isBasic = false; - return; + return null; } if (plainSelect.getWhere() != null) { Expression where = plainSelect.getWhere(); ExpressionAdapter expressionAdapter = new ExpressionAdapter(); - where.accept(expressionAdapter); + where.accept(expressionAdapter, null); if (!expressionAdapter.isBasic) { isBasic = false; - return; + return null; } } GroupByElement groupBy = plainSelect.getGroupBy(); if (groupBy == null) { isBasic = false; - return; + return null; } - - for (Expression expression : groupBy.getGroupByExpressionList().getExpressions()) { + ExpressionList<Expression> groupByExpressionList = groupBy.getGroupByExpressionList(); + for (Expression expression : groupByExpressionList) { ExpressionAdapter expressionAdapter = new ExpressionAdapter(); - expression.accept(expressionAdapter); + expression.accept(expressionAdapter, null); if (!expressionAdapter.isBasic) { isBasic = false; - return; + return null; } } @@ -120,55 +121,56 @@ public class TimeBasedShardingUtil { for (OrderByElement orderByElement : orderByElements) { Expression expression = orderByElement.getExpression(); ExpressionAdapter expressionAdapter = new ExpressionAdapter(); - expression.accept(expressionAdapter); + expression.accept(expressionAdapter, null); if (!expressionAdapter.isBasic) { isBasic = false; - return; + return null; } } if (plainSelect.getHaving() != null) { Expression having = plainSelect.getHaving(); ExpressionAdapter expressionAdapter = new ExpressionAdapter(); - having.accept(expressionAdapter); + having.accept(expressionAdapter, null); if (!expressionAdapter.isBasic) { isBasic = false; - return; + return null; } } - if(plainSelect.getLimit() != null && plainSelect.getLimit().getOffset() != null){ + if (plainSelect.getLimit() != null && plainSelect.getLimit().getOffset() != null) { isBasic = false; - return; + return null; } + return null; } @Override - public void visit(SetOperationList setOpList) { + public Object visit(SetOperationList setOpList, Object context) { isBasic = false; - return; + return null; } @Override - public void visit(WithItem withItem) { + public Object visit(WithItem withItem, Object context) { isBasic = false; - return; + return null; } @Override - public void visit(ValuesStatement aThis) { + public Object visit(Values aThis, Object context) { isBasic = false; - return; + return null; } } - private static class ExpressionAdapter extends ExpressionVisitorAdapter { + private static class ExpressionAdapter extends ExpressionVisitorAdapter<Object> { private boolean isBasic = true; @Override - public void visit(SubSelect subSelect) { + public Object visit(Select select, Object context) { isBasic = false; - return; + return null; } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/TopInnerSelectItemVisitor.java b/src/main/java/com/mesalab/common/utils/sqlparser/TopInnerSelectItemVisitor.java index 512fc414..9f490514 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/TopInnerSelectItemVisitor.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/TopInnerSelectItemVisitor.java @@ -2,13 +2,11 @@ package com.mesalab.common.utils.sqlparser; import cn.hutool.core.util.StrUtil; import com.google.common.collect.Maps; -import lombok.SneakyThrows; import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.*; -import net.sf.jsqlparser.statement.values.ValuesStatement; import org.apache.commons.compress.utils.Lists; import java.util.List; @@ -16,7 +14,6 @@ import java.util.Map; /** - * * @Classname InnerSelectItemVisitor * @Date 2021/7/20 3:39 下午 * @Author wWei @@ -35,35 +32,36 @@ public class TopInnerSelectItemVisitor implements OrderByVisitor, GroupByVisitor public void rewrite(PlainSelect plainSelect) { - for (SelectItem selectItem : plainSelect.getSelectItems()) { - selectItem.accept(this); + for (SelectItem<?> selectItem : plainSelect.getSelectItems()) { + selectItem.accept(this, null); } if (!StrUtil.isBlankIfStr(plainSelect.getGroupBy())) { - plainSelect.getGroupBy().accept(this); + plainSelect.getGroupBy().accept(this, null); } if (!StrUtil.isBlankIfStr(plainSelect.getOrderByElements())) { for (OrderByElement orderByElement : plainSelect.getOrderByElements()) { - orderByElement.accept(this); + orderByElement.accept(this, null); } } - plainSelect.accept(this); + plainSelect.accept(this, null); } @Override - public void visit(GroupByElement groupByElement) { - List<Expression> groupByExpressions = groupByElement.getGroupByExpressions(); + public Object visit(GroupByElement groupByElement, Object context) { + ExpressionList<Expression> groupByExpressions = groupByElement.getGroupByExpressionList(); for (int i = 0; i < groupByExpressions.size(); i++) { Expression expression = groupByExpressions.get(i); if (exprAlias.containsKey(expression.toString())) { Column column = new Column(exprAlias.get(expression.toString())); - groupByElement.getGroupByExpressions().set(i, column); + groupByElement.getGroupByExpressionList().set(i, column); } } groupByList.addAll(groupByExpressions); + return null; } @Override - public void visit(OrderByElement orderByElement) { + public Object visit(OrderByElement orderByElement, Object context) { Expression expression = orderByElement.getExpression(); String alias = exprAlias.get(expression.toString()); if (exprAlias.containsKey(expression.toString())) { @@ -73,11 +71,17 @@ public class TopInnerSelectItemVisitor implements OrderByVisitor, GroupByVisitor } else { OrderByList.add(expression); } + return null; } @Override - public void visit(PlainSelect plainSelect) { - List<SelectItem> selectItems = plainSelect.getSelectItems(); + public Object visit(ParenthesedSelect parenthesedSelect, Object context) { + return null; + } + + @Override + public Object visit(PlainSelect plainSelect, Object context) { + List<SelectItem<?>> selectItems = plainSelect.getSelectItems(); List<Expression> list = Lists.newArrayList(); list.addAll(OrderByList); list.addAll(groupByList); @@ -86,42 +90,46 @@ public class TopInnerSelectItemVisitor implements OrderByVisitor, GroupByVisitor || exprAlias.containsValue(expression.toString())) { continue; } - SelectExpressionItem selectItem = new SelectExpressionItem(); + SelectItem<Expression> selectItem = new SelectItem<>(); selectItem.setExpression(expression); selectItem.setAlias(new Alias(expression.toString() .substring(0, expression.toString().indexOf("(")) + (int) (Math.random() * 100), true)); selectItems.add(selectItem); exprAlias.put(selectItem.getExpression().toString(), selectItem.getAlias().getName()); } + return null; } @Override - public void visit(SetOperationList setOperationList) { - + public Object visit(TableStatement tableStatement, Object context) { + return null; } @Override - public void visit(WithItem withItem) { - + public Object visit(LateralSubSelect lateralSubSelect, Object context) { + return null; } @Override - public void visit(ValuesStatement valuesStatement) { - + public Object visit(Values values, Object context) { + return null; } @Override - public void visit(AllColumns allColumns) { + public Object visit(SelectItem selectItem, Object context) { + if (!StrUtil.isBlankIfStr(selectItem.getAlias())) { + exprAlias.put(selectItem.getExpression().toString(), selectItem.getAlias().getName()); + } + return null; } @Override - public void visit(AllTableColumns allTableColumns) { + public Object visit(SetOperationList setOpList, Object context) { + return null; } @Override - public void visit(SelectExpressionItem selectExpressionItem) { - if (!StrUtil.isBlankIfStr(selectExpressionItem.getAlias())) { - exprAlias.put(selectExpressionItem.getExpression().toString(), selectExpressionItem.getAlias().getName()); - } + public Object visit(WithItem withItem, Object context) { + return null; } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/TopOuterSelectItemVisitor.java b/src/main/java/com/mesalab/common/utils/sqlparser/TopOuterSelectItemVisitor.java index ff9a3233..48cb093e 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/TopOuterSelectItemVisitor.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/TopOuterSelectItemVisitor.java @@ -16,7 +16,6 @@ import java.util.Map; import java.util.stream.Collectors; /** - * * @Classname OuterSelectItemVisitor * @Date * @Author @@ -25,7 +24,7 @@ public class TopOuterSelectItemVisitor implements SelectItemVisitor { public void rewrite(PlainSelect outerSelect, PlainSelect innerSelect) throws JSQLParserException { Select parse = (Select) CCJSqlParserUtil.parse("SELECT " + outerSelect.getSelectItems().stream().map(Object::toString) .collect(Collectors.joining(", ")) + " FROM ( " + innerSelect + ") "); - PlainSelect plainSelect = (PlainSelect) parse.getSelectBody(); + PlainSelect plainSelect = parse.getPlainSelect(); outerSelect.setFromItem(plainSelect.getFromItem()); outerSelect.setWhere(null); outerSelect.setGroupByElement(innerSelect.getGroupBy()); @@ -34,41 +33,31 @@ public class TopOuterSelectItemVisitor implements SelectItemVisitor { Map<String, String> exprAlias = Maps.newHashMap(); for (SelectItem selectItem : innerSelect.getSelectItems()) { - SelectExpressionItem item = (SelectExpressionItem) selectItem; - Expression expression = item.getExpression(); - String alias = item.getAlias().getName(); + Expression expression = selectItem.getExpression(); + String alias = selectItem.getAlias().getName(); exprAlias.put(expression.toString(), alias); } List<OrderByElement> orderByElements = innerSelect.getOrderByElements(); for (OrderByElement orderByElement : orderByElements) { String orderByStr = orderByElement.getExpression().toString(); if (exprAlias.containsKey(orderByStr)) { - orderByElement.getExpression().accept(SQLVisitorUtil.getVisitorOfRenameColumn(exprAlias.get(orderByStr))); + orderByElement.getExpression().accept(SQLVisitorUtil.getVisitorOfRenameColumn(exprAlias.get(orderByStr)), null); } } outerSelect.setOrderByElements(innerSelect.getOrderByElements()); - List<SelectItem> selectItems = outerSelect.getSelectItems(); - for (SelectItem selectItem : selectItems) { - SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem; - selectExpressionItem.accept(this); + List<SelectItem<?>> selectItems = outerSelect.getSelectItems(); + for (SelectItem<?> selectItem : selectItems) { + selectItem.accept(this, null); } } @Override - public void visit(AllColumns allColumns) { - } - - @Override - public void visit(AllTableColumns allTableColumns) { - } - - @Override - public void visit(SelectExpressionItem selectExpressionItem) { - if (StrUtil.isBlankIfStr(selectExpressionItem.getAlias())) { - return; + public Object visit(SelectItem selectItem, Object context) { + if (StrUtil.isBlankIfStr(selectItem.getAlias())) { + return null; } - String name = selectExpressionItem.getAlias().getName(); - Expression expression = selectExpressionItem.getExpression(); + String name = selectItem.getAlias().getName(); + Expression expression = selectItem.getExpression(); if (!StrUtil.isBlankIfStr(name)) { if (expression instanceof Column) { Column column = (Column) expression; @@ -85,5 +74,6 @@ public class TopOuterSelectItemVisitor implements SelectItemVisitor { function.setParameters(expressionList); } } + return null; } } diff --git a/src/main/java/com/mesalab/common/utils/sqlparser/TopSQLVisitor.java b/src/main/java/com/mesalab/common/utils/sqlparser/TopSQLVisitor.java index d82ccc18..ab64fcca 100644 --- a/src/main/java/com/mesalab/common/utils/sqlparser/TopSQLVisitor.java +++ b/src/main/java/com/mesalab/common/utils/sqlparser/TopSQLVisitor.java @@ -10,6 +10,7 @@ import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Function; import net.sf.jsqlparser.expression.LongValue; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.*; @@ -23,12 +24,11 @@ import java.util.stream.Collectors; /** - * * @Classname TopSQLVisitor * @Date 2021/7/20 3:39 下午 * @Author wWei */ -public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItemVisitor { +public class TopSQLVisitor<T> implements OrderByVisitor<T>, GroupByVisitor<T>, SelectItemVisitor<T> { private static final Log log = LogFactory.get(); private static final long TOP_INNER_LIMIT_RATIO = 10; private static final long TOP_INNER_LIMIT_LOWER = 1000; @@ -38,8 +38,8 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem private List<String> selectItemExprList; private List<String> selectItemAliasList; private List<Function> functionList; - private SelectBody innerSelectBody = null; - private SelectBody originalSelectBody = null; + private Select innerSelectBody = null; + private Select originalSelectBody = null; public TopSQLVisitor() { this.selectItemExprList = Lists.newArrayList(); @@ -51,20 +51,23 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem /** * 验证SQL是否符合Top SQL优化条件: - * Select expr,count/sum... from Table group by expr order by expr desc limit N + * Select expr,count/sum... from Table group by expr order by expr desc limit N + * * @param sql * @return */ public boolean isValid(String sql) { boolean isValid = false; try { - SelectBody selectBody = ((Select) CCJSqlParserUtil.parse(sql)).getSelectBody(); - this.originalSelectBody = selectBody; - innerSelectBody = getInnerSelectBody(selectBody); - if (StringUtil.isNotEmpty(innerSelectBody)) { - isValid = parseAndValidation((PlainSelect) innerSelectBody); - } + Select select = ((Select) CCJSqlParserUtil.parse(sql)); + if (select instanceof PlainSelect) { + this.originalSelectBody = select.getPlainSelect(); + innerSelectBody = getInnerSelectBody(select.getPlainSelect()); + if (StringUtil.isNotEmpty(innerSelectBody)) { + isValid = parseAndValidation((PlainSelect) innerSelectBody); + } + } } catch (JSQLParserException e) { isValid = false; log.error("Parse SQL error ", e); @@ -78,11 +81,11 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem try { String sql = innerSelectBody.toString(); Select innerSelect = (Select) CCJSqlParserUtil.parse(sql); - PlainSelect plainInnerSelect = (PlainSelect) innerSelect.getSelectBody(); + PlainSelect plainInnerSelect = innerSelect.getPlainSelect(); new TopInnerSelectItemVisitor().rewrite(plainInnerSelect); Select outerSelect = (Select) CCJSqlParserUtil.parse(sql); - PlainSelect plainOuterSelect = (PlainSelect) outerSelect.getSelectBody(); + PlainSelect plainOuterSelect = outerSelect.getPlainSelect(); new TopOuterSelectItemVisitor().rewrite(plainOuterSelect, plainInnerSelect); return this.originalSelectBody.toString().replace(this.innerSelectBody.toString(), appendSetting(plainOuterSelect)); } catch (JSQLParserException e) { @@ -104,11 +107,10 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem private void rewriteInnerLimit(PlainSelect plainSelectOut) { FromItem fromItem = plainSelectOut.getFromItem(); - if (fromItem instanceof SubSelect) { - SubSelect subSelect = (SubSelect) fromItem; - SelectBody selectBody = subSelect.getSelectBody(); - if (selectBody instanceof PlainSelect) { - Limit limit = ((PlainSelect) selectBody).getLimit(); + if (fromItem instanceof ParenthesedSelect) { + Select select = ((ParenthesedSelect) fromItem).getSelect(); + if (select instanceof PlainSelect) { + Limit limit = select.getPlainSelect().getLimit(); if (StringUtil.isNotEmpty(limit)) { long rowCount = Long.parseLong(limit.getRowCount().toString()); if (StringUtil.isNotEmpty(limit.getOffset())) { @@ -124,26 +126,29 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem } } } + /** * 递归遍历获取最内层SQL,内层SQL非标准查询将返回NULL - * @param selectBody + * + * @param plainSelect * @return */ - private SelectBody getInnerSelectBody(SelectBody selectBody) { - if (selectBody instanceof PlainSelect) { - FromItem fromItem = ((PlainSelect) selectBody).getFromItem(); - if (fromItem instanceof SubSelect) { - return getInnerSelectBody(((SubSelect) fromItem).getSelectBody()); - } else { - return selectBody; + private PlainSelect getInnerSelectBody(PlainSelect plainSelect) { + FromItem fromItem = plainSelect.getFromItem(); + if (fromItem instanceof ParenthesedSelect) { + Select innerSelect = ((ParenthesedSelect) fromItem).getSelect(); + if (innerSelect instanceof PlainSelect) { + return getInnerSelectBody(innerSelect.getPlainSelect()); } - } else { return null; + } else { + return plainSelect; } } /** * 对当前SQL解析并验证是否符合TOP优化条件 + * * @param plainSelect * @return */ @@ -151,15 +156,15 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem if (plainSelect == null) { return false; } - for (SelectItem item : plainSelect.getSelectItems()) { - item.accept(this); + for (SelectItem<?> item : plainSelect.getSelectItems()) { + item.accept(this, null); } if (!StrUtil.isBlankIfStr(plainSelect.getGroupBy())) { - plainSelect.getGroupBy().accept(this); + plainSelect.getGroupBy().accept(this, null); } if (!StrUtil.isBlankIfStr(plainSelect.getOrderByElements())) { for (OrderByElement orderByElement : plainSelect.getOrderByElements()) { - orderByElement.accept(this); + orderByElement.accept(this, null); } } @@ -168,30 +173,30 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem } if (groupByList.isEmpty() || orderByList.isEmpty()) { - return false; + return false; } if (selectItemExprList.size() > (groupByList.size() + functionList.size())) { return false; } - List unsupportedFunctionList = functionList.stream().filter(o -> + List unsupportedFunctionList = functionList.stream().filter(o -> StringUtil.isBlank(SQLFunctionUtil.getDistributedGroupByFunction(o.getName().toLowerCase(Locale.ROOT)))).collect(Collectors.toList()); - if(unsupportedFunctionList.size() > 0) { + if (unsupportedFunctionList.size() > 0) { return false; } if (functionList.stream().anyMatch(o -> (o.isDistinct()) || o.isUnique())) { return false; } - List unsupportedGroupByList = groupByList.stream().filter(o -> - !selectItemExprList.contains(o) && !selectItemAliasList.contains(o) ).collect(Collectors.toList()); - if(unsupportedGroupByList.size() > 0) { + List unsupportedGroupByList = groupByList.stream().filter(o -> + !selectItemExprList.contains(o) && !selectItemAliasList.contains(o)).collect(Collectors.toList()); + if (unsupportedGroupByList.size() > 0) { return false; } - List unsupportedOrderByList = orderByList.stream().filter(o -> - !selectItemExprList.contains(o) && !selectItemAliasList.contains(o) ).collect(Collectors.toList()); - if(unsupportedOrderByList.size() > 0) { + List unsupportedOrderByList = orderByList.stream().filter(o -> + !selectItemExprList.contains(o) && !selectItemAliasList.contains(o)).collect(Collectors.toList()); + if (unsupportedOrderByList.size() > 0) { return false; } @@ -199,44 +204,40 @@ public class TopSQLVisitor implements OrderByVisitor, GroupByVisitor, SelectItem } @Override - public void visit(GroupByElement groupByElement) { - groupByElement.getGroupByExpressions().forEach(o -> this.groupByList.add(o.toString())); + public <S> T visit(GroupByElement groupByElement, S context) { + ExpressionList<?> groupByExpressionList = groupByElement.getGroupByExpressionList(); + groupByExpressionList.forEach(o -> this.groupByList.add(o.toString())); + return null; } @Override - public void visit(OrderByElement orderByElement) { + public <S> T visit(OrderByElement orderByElement, S context) { Expression expression = orderByElement.getExpression(); this.orderByList.add(expression.toString()); + return null; } @Override - public void visit(AllColumns allColumns) { - } - - @Override - public void visit(AllTableColumns allTableColumns) { - } - - @Override - public void visit(SelectExpressionItem selectExpressionItem) { - Expression expression = selectExpressionItem.getExpression(); - this.selectItemExprList.add(expression.toString()); + public <S> T visit(SelectItem<? extends Expression> selectItem, S context) { + Expression expression = selectItem.getExpression(); + this.selectItemExprList.add(expression.toString()); if (expression instanceof Function) { functionList.add(((Function) expression)); } - if (StrUtil.isEmptyIfStr(selectExpressionItem.getAlias())) { - if (expression instanceof Column) { - Column column = (Column) (expression); - Alias alias = new Alias(column.getColumnName()); - selectExpressionItem.setAlias(alias); - this.selectItemAliasList.add(selectExpressionItem.getAlias().getName()); - } else if (expression instanceof Function) { - selectExpressionItem.setAlias(new Alias("\""+ expression.toString() + "\"")); - this.selectItemAliasList.add(selectExpressionItem.getAlias().getName()); - } - - } else { - this.selectItemAliasList.add(selectExpressionItem.getAlias().getName()); - } + if (StrUtil.isEmptyIfStr(selectItem.getAlias())) { + if (expression instanceof Column) { + Column column = (Column) (expression); + Alias alias = new Alias(column.getColumnName()); + selectItem.setAlias(alias); + this.selectItemAliasList.add(selectItem.getAlias().getName()); + } else if (expression instanceof Function) { + selectItem.setAlias(new Alias("\"" + expression + "\"")); + this.selectItemAliasList.add(selectItem.getAlias().getName()); + } + + } else { + this.selectItemAliasList.add(selectItem.getAlias().getName()); + } + return null; } } diff --git a/src/main/java/com/mesalab/qgw/dialect/ClickHouseDialect.java b/src/main/java/com/mesalab/qgw/dialect/ClickHouseDialect.java index 99970843..e2d6c981 100644 --- a/src/main/java/com/mesalab/qgw/dialect/ClickHouseDialect.java +++ b/src/main/java/com/mesalab/qgw/dialect/ClickHouseDialect.java @@ -402,7 +402,11 @@ public class ClickHouseDialect extends AbstractDataSourceDialect { RewriteTable deParser = new RewriteTable(expressionDeParser, buffer); expressionDeParser.setSelectVisitor(deParser); expressionDeParser.setBuffer(buffer); - select.getSelectBody().accept(deParser); + if (select instanceof PlainSelect) { + select.getPlainSelect().accept(deParser, null); + } else if (select instanceof SetOperationList) { + select.getSetOperationList().accept(deParser, null); + } sql = buffer.toString(); } catch (JSQLParserException | RuntimeException e) { log.error("SQL Rewrite add tableName and Alias Error: ", e); diff --git a/src/main/java/com/mesalab/qgw/dialect/HbaseDialect.java b/src/main/java/com/mesalab/qgw/dialect/HbaseDialect.java index f7bb4343..1122570f 100644 --- a/src/main/java/com/mesalab/qgw/dialect/HbaseDialect.java +++ b/src/main/java/com/mesalab/qgw/dialect/HbaseDialect.java @@ -26,7 +26,9 @@ import com.geedgenetworks.utils.StringUtil; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; +import net.sf.jsqlparser.statement.select.SetOperationList; import java.sql.*; @@ -97,7 +99,11 @@ public class HbaseDialect extends AbstractDataSourceDialect { sql = SQLFunctionUtil.generateDateFunction(sql, DBEngineType.HBASE.getValue()); try { Select select = (Select) CCJSqlParserUtil.parse(sql); - select.getSelectBody().accept(SQLVisitorUtil.getVisitorOfEscapeMetadataWithDoubleQuote()); + if (select instanceof PlainSelect) { + select.getPlainSelect().accept(SQLVisitorUtil.getVisitorOfEscapeMetadataWithDoubleQuote(), null); + } else if (select instanceof SetOperationList) { + select.getSetOperationList().accept(SQLVisitorUtil.getVisitorOfEscapeMetadataWithDoubleQuote(), null); + } return select.toString(); } catch (JSQLParserException | RuntimeException e) { log.error("SQL Syntax Error: Converter SQL Syntax Error, SQL is:{}, Error is:{}", sql, e); diff --git a/src/main/java/com/mesalab/qgw/model/basic/SelectStatement.java b/src/main/java/com/mesalab/qgw/model/basic/SelectStatement.java index c3d1c82f..806a090e 100644 --- a/src/main/java/com/mesalab/qgw/model/basic/SelectStatement.java +++ b/src/main/java/com/mesalab/qgw/model/basic/SelectStatement.java @@ -29,7 +29,7 @@ public class SelectStatement { private String partitionKey; private List<Join> joins; private FromItem fromItem; - private List<SelectItem> selectItems; + private List<SelectItem<?>> selectItems; private Map<String, String> aliasFields = Maps.newHashMap(); private Expression whereExpression; private GroupByElement groupByElement; @@ -38,7 +38,7 @@ public class SelectStatement { private String limit; private boolean isEnableLimit; - private SubSelect subSelect; + private ParenthesedSelect parenthesedSelect; private List<SelectStatement> subSqlQuerySources = Lists.newArrayList(); private Set<UDF> udfSet = Sets.newHashSet(); @@ -58,14 +58,14 @@ public class SelectStatement { if (groupByElement == null) { return Maps.newHashMap(); } - ExpressionList groupByExpressionList = groupByElement.getGroupByExpressionList(); + ExpressionList<Expression> groupByExpressionList = groupByElement.getGroupByExpressionList(); groupBy: - for (Expression expression : groupByExpressionList.getExpressions()) { + for (Expression expression : groupByExpressionList) { String groupBy = expression.toString(); groupBy = SQLHelper.removeQuotesAndBackticks(groupBy); if (expression instanceof Function && SQLFunctionUtil.ROLLUP.equalsIgnoreCase(((Function) expression).getName())) { - List<Expression> funParamList = ((Function) expression).getParameters().getExpressions(); + ExpressionList<?> funParamList = ((Function) expression).getParameters(); paramGroupBy: for (Expression param : funParamList) { String paramGroupBy = param.toString(); diff --git a/src/main/java/com/mesalab/qgw/model/basic/udf/DATETIME_FLOOR_WITH_FILL.java b/src/main/java/com/mesalab/qgw/model/basic/udf/DATETIME_FLOOR_WITH_FILL.java index 6327392a..f538b89f 100644 --- a/src/main/java/com/mesalab/qgw/model/basic/udf/DATETIME_FLOOR_WITH_FILL.java +++ b/src/main/java/com/mesalab/qgw/model/basic/udf/DATETIME_FLOOR_WITH_FILL.java @@ -332,7 +332,7 @@ public class DATETIME_FLOOR_WITH_FILL implements UDF { boolean isOriginalDataSource = false; while (!isOriginalDataSource) { FillParam currentParam = new FillParam(); - if (currentSource.getSubSelect() == null) { + if (currentSource.getParenthesedSelect() == null) { isOriginalDataSource = true; currentParam.setPartitionKey(currentSource.getPartitionKey()); } diff --git a/src/main/java/com/mesalab/qgw/model/basic/udf/TIME_FLOOR_WITH_FILL.java b/src/main/java/com/mesalab/qgw/model/basic/udf/TIME_FLOOR_WITH_FILL.java index 9d4b0ef7..b056554f 100644 --- a/src/main/java/com/mesalab/qgw/model/basic/udf/TIME_FLOOR_WITH_FILL.java +++ b/src/main/java/com/mesalab/qgw/model/basic/udf/TIME_FLOOR_WITH_FILL.java @@ -355,7 +355,7 @@ public class TIME_FLOOR_WITH_FILL implements UDF { boolean isOriginalDataSource = false; while (!isOriginalDataSource) { FillParam currentParam = new FillParam(); - if (currentSource.getSubSelect() == null) { + if (currentSource.getParenthesedSelect() == null) { isOriginalDataSource = true; currentParam.setPartitionKey(currentSource.getPartitionKey()); } diff --git a/src/main/java/com/mesalab/qgw/service/RewriteTable.java b/src/main/java/com/mesalab/qgw/service/RewriteTable.java index 2a91b570..2d7ab52a 100644 --- a/src/main/java/com/mesalab/qgw/service/RewriteTable.java +++ b/src/main/java/com/mesalab/qgw/service/RewriteTable.java @@ -24,7 +24,7 @@ public class RewriteTable extends SelectDeParser { } @Override - public void visit(Table table) { + public StringBuilder visit(Table table, Object context) { if (StringUtil.isBlank(table.getSchemaName())) { table.setSchemaName(databaseService.getDBNameByTableName(table.getName())); } @@ -36,11 +36,12 @@ public class RewriteTable extends SelectDeParser { buffer.append(table.getFullyQualifiedName()); Pivot pivot = table.getPivot(); if (pivot != null) { - pivot.accept(this); + pivot.accept(this, null); } Alias alias = table.getAlias(); if (alias != null) { buffer.append(alias); } + return null; } }
\ No newline at end of file diff --git a/src/main/java/com/mesalab/qgw/service/impl/DslServiceImpl.java b/src/main/java/com/mesalab/qgw/service/impl/DslServiceImpl.java index 0f61db36..f71c484e 100644 --- a/src/main/java/com/mesalab/qgw/service/impl/DslServiceImpl.java +++ b/src/main/java/com/mesalab/qgw/service/impl/DslServiceImpl.java @@ -34,10 +34,7 @@ import com.mesalab.qgw.service.DatabaseService; import com.mesalab.qgw.service.SQLSyncQueryService; import com.mesalab.services.common.property.SqlPropertySourceFactory; import net.sf.jsqlparser.JSQLParserException; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.ExpressionVisitorAdapter; -import net.sf.jsqlparser.expression.LongValue; -import net.sf.jsqlparser.expression.StringValue; +import net.sf.jsqlparser.expression.*; import net.sf.jsqlparser.expression.operators.relational.*; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; @@ -330,7 +327,7 @@ public class DslServiceImpl implements DSLService { } catch (JSQLParserException e) { throw new BusinessException(HttpStatusCodeEnum.BAD_REQUEST.getCode(), CommonErrorCode.UNKNOWN_EXCEPTION.getCode(), String.format(CommonErrorCode.UNKNOWN_EXCEPTION.getMessage(), e.getMessage())); } - expression.accept(expressionVisitorAdapter); + expression.accept(expressionVisitorAdapter, null); Iterator<Range> iterator = ranges.iterator(); while (iterator.hasNext()) { Range next = iterator.next(); @@ -375,9 +372,9 @@ public class DslServiceImpl implements DSLService { } private static ExpressionVisitorAdapter getExpressionVisitorAdapter(List<Match> matches, List<Range> ranges) { - ExpressionVisitorAdapter expressionVisitorAdapter = new ExpressionVisitorAdapter() { + return new ExpressionVisitorAdapter<Object>() { @Override - public void visit(LikeExpression expr) { + public Object visit(LikeExpression expr, Object context) { String left = String.valueOf(expr.getLeftExpression()); String right = ((StringValue) expr.getRightExpression()).getValue(); String type = ""; @@ -408,10 +405,11 @@ public class DslServiceImpl implements DSLService { match.setFieldValues(Lists.newArrayList(right)); matches.add(match); } + return null; } @Override - public void visit(EqualsTo expr) { + public Object visit(EqualsTo expr, Object context) { String left = String.valueOf(expr.getLeftExpression()); Object right; if (expr.getRightExpression() instanceof LongValue) { @@ -432,16 +430,18 @@ public class DslServiceImpl implements DSLService { range.setFieldValues(Lists.newArrayList(right)); ranges.add(range); } + return null; } @Override - public void visit(InExpression expr) { - ItemsList rightItemsList = expr.getRightItemsList(); - if (rightItemsList instanceof ExpressionList && ((ExpressionList) rightItemsList).getExpressions().get(0) instanceof LongValue) { + public Object visit(InExpression expr, Object context) { + Expression rightExpression = expr.getRightExpression(); + if (rightExpression instanceof ExpressionList && ((ExpressionList<?>) rightExpression).get(0) instanceof LongValue) { intParseIn(expr); } else { strParseIn(expr); } + return null; } private void intParseIn(InExpression expr) { @@ -449,21 +449,17 @@ public class DslServiceImpl implements DSLService { if (ranges.stream().anyMatch(o -> o.getFieldKey().equals(left) && o.getType().equals(RangeTypeEnum.EQ.getType()))) { for (Range range : ranges) { if (range.getFieldKey().equals(left) && range.getType().equals(RangeTypeEnum.EQ.getType())) { - ItemsList rightItemsList = expr.getRightItemsList(); - rightItemsList.accept(new ItemsListVisitorAdapter() { - @Override - public void visit(ExpressionList expressionList) { - for (Expression expression : expressionList.getExpressions()) { - if (expression instanceof StringValue) { - range.getFieldValues().add(((StringValue) expression).getValue()); - } else if (expression instanceof LongValue) { - range.getFieldValues().add(((LongValue) expression).getValue()); - } - + Expression rightExpression = expr.getRightExpression(); + if (rightExpression instanceof ExpressionList) { + List<Expression> expressions = (ExpressionList) rightExpression; + for (Expression expression : expressions) { + if (expression instanceof StringValue) { + range.getFieldValues().add(((StringValue) expression).getValue()); + } else if (expression instanceof LongValue) { + range.getFieldValues().add(((LongValue) expression).getValue()); } } - - }); + } } } } else { @@ -471,20 +467,17 @@ public class DslServiceImpl implements DSLService { range.setFieldKey(left); range.setFieldValues(Lists.newArrayList()); range.setType(RangeTypeEnum.EQ.getType()); - ItemsList rightItemsList = expr.getRightItemsList(); - rightItemsList.accept(new ItemsListVisitorAdapter() { - @Override - public void visit(ExpressionList expressionList) { - for (Expression expression : expressionList.getExpressions()) { - if (expression instanceof StringValue) { - range.getFieldValues().add(((StringValue) expression).getValue()); - } else if (expression instanceof LongValue) { - range.getFieldValues().add(((LongValue) expression).getValue()); - } - + Expression rightExpression = expr.getRightExpression(); + if (rightExpression instanceof ExpressionList) { + List<Expression> expressions = (ExpressionList) rightExpression; + for (Expression expression : expressions) { + if (expression instanceof StringValue) { + range.getFieldValues().add(((StringValue) expression).getValue()); + } else if (expression instanceof LongValue) { + range.getFieldValues().add(((LongValue) expression).getValue()); } } - }); + } ranges.add(range); } } @@ -494,21 +487,16 @@ public class DslServiceImpl implements DSLService { if (matches.stream().anyMatch(o -> o.getFieldKey().equals(left) && o.getType().equals(MatchEnum.EXACTLY.getType()))) { for (Match match : matches) { if (match.getFieldKey().equals(left) && match.getType().equals(MatchEnum.EXACTLY.getType())) { - ItemsList rightItemsList = expr.getRightItemsList(); - rightItemsList.accept(new ItemsListVisitorAdapter() { - @Override - public void visit(ExpressionList expressionList) { - for (Expression expression : expressionList.getExpressions()) { - if (expression instanceof StringValue) { - match.getFieldValues().add(((StringValue) expression).getValue()); - } else if (expression instanceof LongValue) { - match.getFieldValues().add(((LongValue) expression).getValue()); - } - + if (expr.getRightExpression() instanceof ExpressionList) { + List<Expression> expressionsList = (ExpressionList) expr.getRightExpression(); + for (Expression expression : expressionsList) { + if (expression instanceof StringValue) { + match.getFieldValues().add(((StringValue) expression).getValue()); + } else if (expression instanceof LongValue) { + match.getFieldValues().add(((LongValue) expression).getValue()); } } - - }); + } } } } else { @@ -516,26 +504,24 @@ public class DslServiceImpl implements DSLService { match.setFieldKey(left); match.setFieldValues(Lists.newArrayList()); match.setType(MatchEnum.EXACTLY.getType()); - ItemsList rightItemsList = expr.getRightItemsList(); - rightItemsList.accept(new ItemsListVisitorAdapter() { - @Override - public void visit(ExpressionList expressionList) { - for (Expression expression : expressionList.getExpressions()) { - if (expression instanceof StringValue) { - match.getFieldValues().add(((StringValue) expression).getValue()); - } else if (expression instanceof LongValue) { - match.getFieldValues().add(((LongValue) expression).getValue()); - } - + Expression rightExpression = expr.getRightExpression(); + if (rightExpression instanceof ExpressionList) { + List<Expression> expressionsList = (ExpressionList) rightExpression; + for (Expression expression : expressionsList) { + if (expression instanceof StringValue) { + match.getFieldValues().add(((StringValue) expression).getValue()); + } else if (expression instanceof LongValue) { + match.getFieldValues().add(((LongValue) expression).getValue()); } + } - }); + } matches.add(match); } } @Override - public void visit(GreaterThan expr) { + public Object visit(GreaterThan expr, Object context) { String left = String.valueOf(expr.getLeftExpression()); Object right; if (expr.getRightExpression() instanceof LongValue) { @@ -556,10 +542,11 @@ public class DslServiceImpl implements DSLService { range.setFieldValues(Lists.newArrayList(right)); ranges.add(range); } + return null; } @Override - public void visit(GreaterThanEquals expr) { + public Object visit(GreaterThanEquals expr, Object context) { String left = String.valueOf(expr.getLeftExpression()); Object right; if (expr.getRightExpression() instanceof LongValue) { @@ -580,9 +567,9 @@ public class DslServiceImpl implements DSLService { range.setFieldValues(Lists.newArrayList(right)); ranges.add(range); } + return null; } }; - return expressionVisitorAdapter; } private SQLQueryContext queryBuild(String sql, boolean isDryRun) { @@ -708,37 +695,6 @@ public class DslServiceImpl implements DSLService { return protocols; } - private String inToLike(String filter) throws JSQLParserException { - List<String> params = Lists.newArrayList(); - List<String> oldExpression = Lists.newArrayList(); - ExpressionVisitorAdapter expressionVisitorAdapter = new ExpressionVisitorAdapter() { - @Override - public void visit(InExpression inExpression) { - if (inExpression.getLeftExpression() != null && "subscriber_id".equals(inExpression.getLeftExpression().toString())) { - oldExpression.add(inExpression.toString()); - ItemsList rightItemsList = inExpression.getRightItemsList(); - if (rightItemsList instanceof ExpressionList) { - ExpressionList items = (ExpressionList) rightItemsList; - List<Expression> expressions = items.getExpressions(); - for (Expression expression : expressions) { - if (expression instanceof StringValue) { - params.add(DigestUtil.md5Hex(((StringValue) expression).getValue()).concat("|%")); - } - - } - } - } - } - }; - Expression expression = CCJSqlParserUtil.parseExpression(filter, false); - String strExpr = expression.toString(); - expression.accept(expressionVisitorAdapter); - if (params.size() > 0 && oldExpression.size() == 1) { - return strExpr.replace(oldExpression.get(0), "( ROWKEY LIKE '" + StrUtil.join("' OR ROWKEY LIKE '", params) + "')"); - } - return filter; - } - private LiveChartProtocol convertStringToObject(String protocolString) { LiveChartProtocol protocol = null; try { diff --git a/src/main/java/com/mesalab/qgw/service/impl/SQLSyncQueryServiceImpl.java b/src/main/java/com/mesalab/qgw/service/impl/SQLSyncQueryServiceImpl.java index a6b2df86..0a104abb 100644 --- a/src/main/java/com/mesalab/qgw/service/impl/SQLSyncQueryServiceImpl.java +++ b/src/main/java/com/mesalab/qgw/service/impl/SQLSyncQueryServiceImpl.java @@ -30,13 +30,13 @@ import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.BinaryExpression; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Function; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.DescribeStatement; import net.sf.jsqlparser.statement.ExplainStatement; import net.sf.jsqlparser.statement.ShowStatement; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.*; -import net.sf.jsqlparser.util.TablesNamesFinder; import org.apache.hbase.thirdparty.com.google.common.collect.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -246,8 +246,8 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { if (StringUtil.isNotEmpty(parentSelectStatement)) { federationSelectStatement = new SelectStatement(); - String tableName = StringUtil.isEmpty(Objects.requireNonNull(parentSelectStatement, "parentSelectStatement is null").getSubSelect().getAlias()) ? parentSelectStatement.getTableNames().get(0) : parentSelectStatement.getSubSelect().getAlias().getName(); - String replace = originalSelectStatement.getSqlBody().replace(parentSelectStatement.getSubSelect().toString(), tableName); + String tableName = StringUtil.isEmpty(Objects.requireNonNull(parentSelectStatement, "parentSelectStatement is null").getParenthesedSelect().getAlias()) ? parentSelectStatement.getTableNames().get(0) : parentSelectStatement.getParenthesedSelect().getAlias().getName(); + String replace = originalSelectStatement.getSqlBody().replace(parentSelectStatement.getParenthesedSelect().toString(), tableName); federationSelectStatement.setSqlBody(replace); federationSelectStatement.getTableNames().add(0, tableName); federationSelectStatement.setLimit(originalSelectStatement.getLimit()); @@ -262,7 +262,7 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { } private boolean isEmptySubSelect(SelectStatement selectStatement) { - return selectStatement == null || StringUtil.isEmpty(selectStatement.getSubSelect()); + return selectStatement == null || StringUtil.isEmpty(selectStatement.getParenthesedSelect()); } @@ -294,11 +294,9 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { sqlQuerySource.getTableNames().add(o); }); sqlQuerySource.setPartitionKey(databaseService.getPartitionKey(sqlQuerySource.getTableNames().get(0))); - SelectBody body = selectStatement.getSelectBody(); - if (body instanceof PlainSelect) { //单条查询 - - PlainSelect select = (PlainSelect) body; + if (selectStatement instanceof PlainSelect) { //单条查询 + PlainSelect select = selectStatement.getPlainSelect(); FromItem fromItem = select.getFromItem(); sqlQuerySource.setFromItem(fromItem); sqlQuerySource.setJoins(select.getJoins()); @@ -307,41 +305,35 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { if (where != null) { sqlQuerySource.setWhereExpression(where); } - - List<SelectItem> selectItemsList = select.getSelectItems(); + List<SelectItem<?>> selectItemsList = select.getSelectItems(); sqlQuerySource.setSelectItems(selectItemsList); - for (SelectItem item : selectItemsList) { - if (item instanceof SelectExpressionItem) { - SelectExpressionItem expressionItem = ((SelectExpressionItem) item); - if (StringUtil.isNotEmpty(expressionItem.getAlias())) { - String aliasName = expressionItem.getAlias().getName(); - aliasName = SQLHelper.removeQuotesAndBackticks(aliasName); - sqlQuerySource.getAliasFields().put(aliasName, expressionItem.getExpression().toString()); - } else { - sqlQuerySource.getAliasFields().put(expressionItem.getExpression().toString(), expressionItem.getExpression().toString()); - } - addUDFSet(sqlQuerySource.getUdfSet(), expressionItem.getExpression());//伪代码:后期需要在SQLQuerySource where对象中提取 - + for (SelectItem<?> item : selectItemsList) { + Expression expr = item.getExpression(); + if (StringUtil.isNotEmpty(item.getAlias())) { + String aliasName = item.getAlias().getName(); + aliasName = SQLHelper.removeQuotesAndBackticks(aliasName); + sqlQuerySource.getAliasFields().put(aliasName, expr.toString()); + } else { + sqlQuerySource.getAliasFields().put(expr.toString(), expr.toString()); } + addUDFSet(sqlQuerySource.getUdfSet(), expr);//伪代码:后期需要在SQLQuerySource where对象中提取 } - GroupByElement groupBy; if (StringUtil.isNotEmpty(groupBy = select.getGroupBy())) { sqlQuerySource.setGroupByElement(groupBy); if (isDrilldown(select, sqlQuerySource.getAliasFields())) { - addRollUpToUDF(sqlQuerySource.getUdfSet(), (Function) groupBy.getGroupByExpressionList().getExpressions().get(0)); + addRollUpToUDF(sqlQuerySource.getUdfSet(), (Function) groupBy.getGroupByExpressionList().get(0)); sqlQuerySource.getUdfSet().removeIf(udf -> udf instanceof TIME_FLOOR_WITH_FILL); sqlQuerySource.getUdfSet().removeIf(udf -> udf instanceof DATETIME_FLOOR_WITH_FILL); } } sqlQuerySource.setOrderByElements(select.getOrderByElements()); - FromItem subItem = select.getFromItem(); - if (subItem instanceof SubSelect) { - SubSelect subSelect = (SubSelect) subItem; - sqlQuerySource.setSubSelect(subSelect); - sqlQuerySource.getSubSqlQuerySources().add(0, parserSQLByAst(String.valueOf(subSelect.getSelectBody()))); + if (fromItem instanceof ParenthesedSelect) { + ParenthesedSelect parenthesedSelect = (ParenthesedSelect) fromItem; + sqlQuerySource.setParenthesedSelect(parenthesedSelect); + sqlQuerySource.getSubSqlQuerySources().add(0, parserSQLByAst(String.valueOf(parenthesedSelect.getSelect()))); } Limit limit = select.getLimit(); if (limit != null) { @@ -354,9 +346,9 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { } - } else if (body instanceof SetOperationList) { // 连接查询 - SetOperationList setOperationList = (SetOperationList) body; - List<SelectBody> selects = setOperationList.getSelects(); + } else if (selectStatement instanceof SetOperationList) { // 连接查询 + SetOperationList setOperationList = selectStatement.getSetOperationList(); + List<Select> selects = setOperationList.getSelects(); //暂时只解析第一个结构,不接受不相同的where if (StringUtil.isNotEmpty(selects)) { SelectStatement parseSql = parserSQLByAst(selects.get(0).toString()); @@ -423,8 +415,8 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { return false; } } - List<Expression> expressions = groupByFunction.getParameters().getExpressions(); - for (Expression expression : expressions) { + ExpressionList<?> parameters = groupByFunction.getParameters(); + for (Expression expression : parameters) { String rollupArg = SQLHelper.removeQuotesAndBackticks(expression.toString()); if (!aliasFields.containsKey(rollupArg) && !aliasFields.containsValue(rollupArg)) { return false; @@ -434,7 +426,9 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { } private static void addRollUpToUDF(Set<UDF> udfSet, Function fun) { - List<Expression> expressions = fun.getParameters().getExpressions(); + ExpressionList<?> parameters = fun.getParameters(); + List<Expression> expressions = Lists.newArrayList(); + expressions.addAll(parameters); UDFElements udfElements = new UDFElements(fun.getName(), expressions); ROLLUP rollup = new ROLLUP(udfElements); udfSet.add(rollup); @@ -454,7 +448,10 @@ public class SQLSyncQueryServiceImpl implements SQLSyncQueryService { if (expr instanceof Function) { Function fun = (Function) expr; if (SQLFunctionUtil.federationUDFFunctions.containsKey(fun.getName().toUpperCase())) { - List<Expression> expressions = fun.getParameters().getExpressions(); + ExpressionList<?> parameters = fun.getParameters(); + List<Expression> expressions = Lists.newArrayList(); + expressions.addAll(parameters); + UDF udf = getUDF(fun, expressions); udfSet.add(udf); } diff --git a/src/main/java/com/mesalab/services/service/impl/JobExecuteService.java b/src/main/java/com/mesalab/services/service/impl/JobExecuteService.java index 9e5da632..b7edd7de 100644 --- a/src/main/java/com/mesalab/services/service/impl/JobExecuteService.java +++ b/src/main/java/com/mesalab/services/service/impl/JobExecuteService.java @@ -39,6 +39,8 @@ import net.sf.jsqlparser.expression.*; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.select.*; import org.joda.time.Period; @@ -336,18 +338,18 @@ public class JobExecuteService implements EnvironmentAware { PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); Optional.ofNullable(plainSelect.getLimit()).ifPresent(x -> sqlIntentContext.setLimit(Long.parseLong(String.valueOf(x.getRowCount())))); Map<String, Object> aliasExpr = Maps.newHashMap(); - for (SelectItem item : plainSelect.getSelectItems()) { - if (!(item instanceof SelectExpressionItem)) { + for (SelectItem<?> item : plainSelect.getSelectItems()) { + if (!(item instanceof Expression)) { return sqlIntentContext; } - SelectExpressionItem selectExprItem = (SelectExpressionItem) item; - if (StringUtil.isEmpty(selectExprItem.getAlias())) { - aliasExpr.put(String.valueOf(selectExprItem.getExpression()), selectExprItem.getExpression()); + if (StringUtil.isEmpty(item.getAlias())) { + aliasExpr.put(String.valueOf(item.getExpression()), item.getExpression()); } else { - aliasExpr.put(selectExprItem.getAlias().getName(), selectExprItem.getExpression()); + aliasExpr.put(item.getAlias().getName(), item.getExpression()); } } - for (Expression groupItem : plainSelect.getGroupBy().getGroupByExpressionList().getExpressions()) { + ExpressionList<Expression> groupByExpressionList = plainSelect.getGroupBy().getGroupByExpressionList(); + for (Expression groupItem : groupByExpressionList) { if (aliasExpr.keySet().stream().noneMatch(o -> o.equals(String.valueOf(groupItem))) && aliasExpr.values().stream().noneMatch(o -> o.equals(String.valueOf(groupItem)))) { return sqlIntentContext; @@ -1285,10 +1287,9 @@ public class JobExecuteService implements EnvironmentAware { } } } - } else if (expression instanceof Parenthesis) { - Parenthesis parenthesis = (Parenthesis) expression; - List<Expression> expressionList = com.clearspring.analytics.util.Lists.newArrayList(); - if (!isOrExpression(parenthesis.getExpression(), expressionList)) { + } else if (expression instanceof ParenthesedExpressionList) { + List<Expression> expressionList = Lists.newArrayList(); + if (!isOrExpression(((ParenthesedExpressionList<?>) expression).get(0), expressionList)) { parseInterval(expressionList, interval, partitionKey, dbEngine); } } |
