mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-13 21:17:08 +00:00
(improvement)(chat) rewrite datediff logic and perfect sql style (#461)
This commit is contained in:
@@ -2,6 +2,12 @@ package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
@Slf4j
|
||||
public class JsqlConstants {
|
||||
|
||||
@@ -9,14 +15,31 @@ public class JsqlConstants {
|
||||
public static final double HALF_YEAR = 0.5d;
|
||||
public static final int SIX_MONTH = 6;
|
||||
public static final String EQUAL = "=";
|
||||
public static final String MINOR_THAN = "<";
|
||||
public static final String MINOR_THAN_EQUALS = "<=";
|
||||
public static final String GREATER_THAN = ">";
|
||||
public static final String GREATER_THAN_EQUALS = ">=";
|
||||
public static final String MINOR_THAN_CONSTANT = " 1 < 2 ";
|
||||
public static final String MINOR_THAN_EQUALS_CONSTANT = " 1 <= 1 ";
|
||||
public static final String GREATER_THAN_CONSTANT = " 2 > 1 ";
|
||||
public static final String GREATER_THAN_EQUALS_CONSTANT = " 1 >= 1 ";
|
||||
public static final String EQUAL_CONSTANT = " 1 = 1 ";
|
||||
|
||||
public static final String IN_CONSTANT = " 1 in (1) ";
|
||||
public static final String LIKE_CONSTANT = "1 like 1";
|
||||
public static final String IN = "IN";
|
||||
public static final Map<String, String> rightMap = Stream.of(
|
||||
new AbstractMap.SimpleEntry<>("<=", "<="),
|
||||
new AbstractMap.SimpleEntry<>("<", "<"),
|
||||
new AbstractMap.SimpleEntry<>(">=", "<="),
|
||||
new AbstractMap.SimpleEntry<>(">", "<"),
|
||||
new AbstractMap.SimpleEntry<>("=", "<="))
|
||||
.collect(toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||
public static final Map<String, String> leftMap = Stream.of(
|
||||
new AbstractMap.SimpleEntry<>("<=", ">="),
|
||||
new AbstractMap.SimpleEntry<>("<", ">"),
|
||||
new AbstractMap.SimpleEntry<>(">=", "<="),
|
||||
new AbstractMap.SimpleEntry<>(">", "<"),
|
||||
new AbstractMap.SimpleEntry<>("=", ">="))
|
||||
.collect(toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
public enum SqlEditEnum {
|
||||
NUMBER_FILTER,
|
||||
DATEDIFF
|
||||
}
|
||||
@@ -342,8 +342,7 @@ public class SqlParserAddHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
sql = SqlParserRemoveHelper.removeNumberCondition(selectStatement.toString());
|
||||
return sql;
|
||||
return SqlParserRemoveHelper.removeNumberFilter(selectStatement.toString());
|
||||
}
|
||||
|
||||
public static String addHaving(String sql, List<Expression> expressionList) {
|
||||
|
||||
@@ -10,6 +10,7 @@ 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.EqualsTo;
|
||||
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
|
||||
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
|
||||
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
|
||||
@@ -17,7 +18,6 @@ import net.sf.jsqlparser.expression.operators.relational.InExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
|
||||
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import net.sf.jsqlparser.statement.select.GroupByElement;
|
||||
@@ -30,8 +30,8 @@ import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Sql Parser remove Helper
|
||||
@@ -73,8 +73,7 @@ public class SqlParserRemoveHelper {
|
||||
removeWhereCondition(plainSelect.getWhere(), removeFieldNames);
|
||||
}
|
||||
});
|
||||
sql = removeNumberCondition(selectStatement.toString());
|
||||
return sql;
|
||||
return removeNumberFilter(selectStatement.toString());
|
||||
}
|
||||
|
||||
private static void removeWhereCondition(Expression whereExpression, Set<String> removeFieldNames) {
|
||||
@@ -84,7 +83,7 @@ public class SqlParserRemoveHelper {
|
||||
removeWhereExpression(whereExpression, removeFieldNames);
|
||||
}
|
||||
|
||||
public static String removeNumberCondition(String sql) {
|
||||
public static String removeNumberFilter(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
if (selectStatement == null) {
|
||||
return sql;
|
||||
@@ -96,10 +95,12 @@ public class SqlParserRemoveHelper {
|
||||
}
|
||||
Expression where = ((PlainSelect) selectBody).getWhere();
|
||||
Expression having = ((PlainSelect) selectBody).getHaving();
|
||||
where = filteredWhereExpression(where);
|
||||
having = filteredWhereExpression(having);
|
||||
((PlainSelect) selectBody).setWhere(where);
|
||||
((PlainSelect) selectBody).setHaving(having);
|
||||
try {
|
||||
((PlainSelect) selectBody).setWhere(filteredExpression(where, SqlEditEnum.NUMBER_FILTER));
|
||||
((PlainSelect) selectBody).setHaving(filteredExpression(having, SqlEditEnum.NUMBER_FILTER));
|
||||
} catch (Exception e) {
|
||||
log.info("replaceFunction has an exception:{}", e.toString());
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
@@ -203,8 +204,7 @@ public class SqlParserRemoveHelper {
|
||||
removeWhereCondition(plainSelect.getHaving(), removeFieldNames);
|
||||
}
|
||||
});
|
||||
sql = removeNumberCondition(selectStatement.toString());
|
||||
return sql;
|
||||
return removeNumberFilter(selectStatement.toString());
|
||||
}
|
||||
|
||||
public static String removeWhere(String sql, List<String> fields) {
|
||||
@@ -252,12 +252,12 @@ public class SqlParserRemoveHelper {
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static Expression filteredWhereExpression(Expression where) {
|
||||
public static Expression filteredExpression(Expression where, SqlEditEnum sqlEditEnum) throws Exception {
|
||||
if (Objects.isNull(where)) {
|
||||
return null;
|
||||
}
|
||||
if (where instanceof Parenthesis) {
|
||||
Expression expression = filteredWhereExpression(((Parenthesis) where).getExpression());
|
||||
Expression expression = filteredExpression(((Parenthesis) where).getExpression(), sqlEditEnum);
|
||||
if (expression != null) {
|
||||
try {
|
||||
Expression parseExpression = CCJSqlParserUtil.parseExpression("(" + expression + ")");
|
||||
@@ -270,19 +270,20 @@ public class SqlParserRemoveHelper {
|
||||
}
|
||||
} else if (where instanceof AndExpression) {
|
||||
AndExpression andExpression = (AndExpression) where;
|
||||
return filteredNumberExpression(andExpression);
|
||||
return filteredLogicExpression(andExpression, sqlEditEnum);
|
||||
} else if (where instanceof OrExpression) {
|
||||
OrExpression orExpression = (OrExpression) where;
|
||||
return filteredNumberExpression(orExpression);
|
||||
return filteredLogicExpression(orExpression, sqlEditEnum);
|
||||
} else {
|
||||
return replaceComparisonOperatorFunction(where);
|
||||
return dealComparisonOperatorFilter(where, sqlEditEnum);
|
||||
}
|
||||
return where;
|
||||
}
|
||||
|
||||
private static <T extends BinaryExpression> Expression filteredNumberExpression(T binaryExpression) {
|
||||
Expression leftExpression = filteredWhereExpression(binaryExpression.getLeftExpression());
|
||||
Expression rightExpression = filteredWhereExpression(binaryExpression.getRightExpression());
|
||||
private static <T extends BinaryExpression> Expression filteredLogicExpression(
|
||||
T binaryExpression, SqlEditEnum sqlEditEnum) throws Exception {
|
||||
Expression leftExpression = filteredExpression(binaryExpression.getLeftExpression(), sqlEditEnum);
|
||||
Expression rightExpression = filteredExpression(binaryExpression.getRightExpression(), sqlEditEnum);
|
||||
if (leftExpression != null && rightExpression != null) {
|
||||
binaryExpression.setLeftExpression(leftExpression);
|
||||
binaryExpression.setRightExpression(rightExpression);
|
||||
@@ -296,40 +297,43 @@ public class SqlParserRemoveHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private static Expression replaceComparisonOperatorFunction(Expression expression) {
|
||||
private static Expression dealComparisonOperatorFilter(Expression expression, SqlEditEnum sqlEditEnum) {
|
||||
if (Objects.isNull(expression)) {
|
||||
return null;
|
||||
}
|
||||
if (expression instanceof GreaterThanEquals) {
|
||||
return removeSingleFilter((GreaterThanEquals) expression);
|
||||
} else if (expression instanceof GreaterThan) {
|
||||
return removeSingleFilter((GreaterThan) expression);
|
||||
} else if (expression instanceof MinorThan) {
|
||||
return removeSingleFilter((MinorThan) expression);
|
||||
} else if (expression instanceof MinorThanEquals) {
|
||||
return removeSingleFilter((MinorThanEquals) expression);
|
||||
} else if (expression instanceof EqualsTo) {
|
||||
return removeSingleFilter((EqualsTo) expression);
|
||||
} else if (expression instanceof NotEqualsTo) {
|
||||
return removeSingleFilter((NotEqualsTo) expression);
|
||||
if (expression instanceof GreaterThanEquals || expression instanceof GreaterThan
|
||||
|| expression instanceof MinorThan || expression instanceof MinorThanEquals
|
||||
|| expression instanceof EqualsTo || expression instanceof NotEqualsTo) {
|
||||
return removeSingleFilter((ComparisonOperator) expression, sqlEditEnum);
|
||||
} else if (expression instanceof InExpression) {
|
||||
InExpression inExpression = (InExpression) expression;
|
||||
Expression leftExpression = inExpression.getLeftExpression();
|
||||
return distinguishNumberCondition(leftExpression, expression);
|
||||
return recursionBase(leftExpression, expression, sqlEditEnum);
|
||||
} else if (expression instanceof LikeExpression) {
|
||||
LikeExpression likeExpression = (LikeExpression) expression;
|
||||
Expression leftExpression = likeExpression.getLeftExpression();
|
||||
return distinguishNumberCondition(leftExpression, expression);
|
||||
return recursionBase(leftExpression, expression, sqlEditEnum);
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
private static <T extends ComparisonOperator> Expression removeSingleFilter(T comparisonExpression) {
|
||||
private static Expression removeSingleFilter(
|
||||
ComparisonOperator comparisonExpression, SqlEditEnum sqlEditEnum) {
|
||||
Expression leftExpression = comparisonExpression.getLeftExpression();
|
||||
return distinguishNumberCondition(leftExpression, comparisonExpression);
|
||||
return recursionBase(leftExpression, comparisonExpression, sqlEditEnum);
|
||||
}
|
||||
|
||||
public static Expression distinguishNumberCondition(Expression leftExpression, Expression expression) {
|
||||
private static Expression recursionBase(Expression leftExpression, Expression expression, SqlEditEnum sqlEditEnum) {
|
||||
if (sqlEditEnum.equals(SqlEditEnum.NUMBER_FILTER)) {
|
||||
return distinguishNumberFilter(leftExpression, expression);
|
||||
}
|
||||
if (sqlEditEnum.equals(SqlEditEnum.DATEDIFF)) {
|
||||
return SqlParserReplaceHelper.distinguishDateDiffFilter(leftExpression, expression);
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
private static Expression distinguishNumberFilter(Expression leftExpression, Expression expression) {
|
||||
if (leftExpression instanceof LongValue) {
|
||||
return null;
|
||||
} else {
|
||||
|
||||
@@ -6,7 +6,9 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.tencent.supersonic.common.util.StringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import net.sf.jsqlparser.expression.Alias;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.Function;
|
||||
@@ -19,6 +21,7 @@ import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
|
||||
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import net.sf.jsqlparser.statement.select.GroupByElement;
|
||||
import net.sf.jsqlparser.statement.select.Join;
|
||||
@@ -267,29 +270,17 @@ public class SqlParserReplaceHelper {
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<PlainSelect> plainSelectList = new ArrayList<>();
|
||||
plainSelectList.add((PlainSelect) selectBody);
|
||||
List<PlainSelect> plainSelects = SqlParserSelectHelper.getPlainSelects(plainSelectList);
|
||||
for (PlainSelect plainSelect : plainSelects) {
|
||||
replaceFunction(plainSelect);
|
||||
Expression where = ((PlainSelect) selectBody).getWhere();
|
||||
try {
|
||||
Expression expression = SqlParserRemoveHelper.filteredExpression(where, SqlEditEnum.DATEDIFF);
|
||||
((PlainSelect) selectBody).setWhere(expression);
|
||||
} catch (Exception e) {
|
||||
log.info("replaceFunction has an exception:{}", e.toString());
|
||||
}
|
||||
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static void replaceFunction(PlainSelect selectBody) {
|
||||
PlainSelect plainSelect = selectBody;
|
||||
|
||||
//1. replace where dataDiff function
|
||||
Expression where = plainSelect.getWhere();
|
||||
FunctionReplaceVisitor visitor = new FunctionReplaceVisitor();
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
//2. add Waiting Expression
|
||||
List<Expression> waitingForAdds = visitor.getWaitingForAdds();
|
||||
addWaitingExpression(plainSelect, where, waitingForAdds);
|
||||
}
|
||||
|
||||
private static void replaceHavingFunction(Map<String, String> functionMap, Expression having) {
|
||||
if (Objects.nonNull(having)) {
|
||||
if (having instanceof AndExpression) {
|
||||
@@ -351,21 +342,6 @@ public class SqlParserReplaceHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addWaitingExpression(PlainSelect plainSelect, Expression where,
|
||||
List<Expression> waitingForAdds) {
|
||||
if (CollectionUtils.isEmpty(waitingForAdds)) {
|
||||
return;
|
||||
}
|
||||
for (Expression expression : waitingForAdds) {
|
||||
if (where == null) {
|
||||
plainSelect.setWhere(expression);
|
||||
} else {
|
||||
where = new AndExpression(where, expression);
|
||||
}
|
||||
}
|
||||
plainSelect.setWhere(where);
|
||||
}
|
||||
|
||||
public static String replaceTable(String sql, String tableName) {
|
||||
if (StringUtils.isEmpty(tableName)) {
|
||||
return sql;
|
||||
@@ -448,5 +424,46 @@ public class SqlParserReplaceHelper {
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static Expression distinguishDateDiffFilter(Expression leftExpression, Expression expression) {
|
||||
if (leftExpression instanceof Function) {
|
||||
Function function = (Function) leftExpression;
|
||||
if (function.getName().equals(JsqlConstants.DATE_FUNCTION)) {
|
||||
ComparisonOperator comparisonOperator = (ComparisonOperator) expression;
|
||||
List<Expression> leftExpressions = function.getParameters().getExpressions();
|
||||
Column field = (Column) function.getParameters().getExpressions().get(1);
|
||||
String columnName = field.getColumnName();
|
||||
try {
|
||||
String startDateValue = DateFunctionHelper.getStartDateStr(comparisonOperator, leftExpressions);
|
||||
String endDateValue = DateFunctionHelper.getEndDateValue(leftExpressions);
|
||||
String dateOperator = comparisonOperator.getStringExpression();
|
||||
String endDateOperator = JsqlConstants.rightMap.get(dateOperator);
|
||||
String startDateOperator = JsqlConstants.leftMap.get(dateOperator);
|
||||
|
||||
String endDateCondExpr = columnName + endDateOperator + StringUtil.getCommaWrap(endDateValue);
|
||||
ComparisonOperator rightExpression = (ComparisonOperator)
|
||||
CCJSqlParserUtil.parseCondExpression(endDateCondExpr);
|
||||
|
||||
String startDateCondExpr = columnName + StringUtil.getSpaceWrap(startDateOperator)
|
||||
+ StringUtil.getCommaWrap(startDateValue);
|
||||
ComparisonOperator newLeftExpression = (ComparisonOperator)
|
||||
CCJSqlParserUtil.parseCondExpression(startDateCondExpr);
|
||||
|
||||
AndExpression andExpression = new AndExpression(newLeftExpression, rightExpression);
|
||||
if (JsqlConstants.GREATER_THAN.equals(dateOperator)
|
||||
|| JsqlConstants.GREATER_THAN_EQUALS.equals(dateOperator)) {
|
||||
return newLeftExpression;
|
||||
} else {
|
||||
return CCJSqlParserUtil.parseCondExpression("(" + andExpression.toString() + ")");
|
||||
}
|
||||
} catch (JSQLParserException e) {
|
||||
log.error("JSQLParserException", e);
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
} else {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user