mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-14 22:25:19 +00:00
(improvment)(chat) refactor the jsqlparser code (#204)
This commit is contained in:
@@ -1,23 +1,20 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.expression.Function;
|
||||
import net.sf.jsqlparser.expression.DoubleValue;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
|
||||
import net.sf.jsqlparser.expression.Function;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
import net.sf.jsqlparser.expression.DoubleValue;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
|
||||
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
|
||||
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator;
|
||||
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
|
||||
|
||||
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
|
||||
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.schema.Column;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -29,7 +26,6 @@ public class FieldlValueReplaceVisitor extends ExpressionVisitorAdapter {
|
||||
private boolean exactReplace;
|
||||
private Map<String, Map<String, String>> filedNameToValueMap;
|
||||
|
||||
|
||||
public FieldlValueReplaceVisitor(boolean exactReplace, Map<String, Map<String, String>> filedNameToValueMap) {
|
||||
this.exactReplace = exactReplace;
|
||||
this.filedNameToValueMap = filedNameToValueMap;
|
||||
@@ -68,27 +64,11 @@ public class FieldlValueReplaceVisitor extends ExpressionVisitorAdapter {
|
||||
if (Objects.isNull(rightExpression) || Objects.isNull(leftExpression)) {
|
||||
return;
|
||||
}
|
||||
String columnName = "";
|
||||
if (leftExpression instanceof Column) {
|
||||
Column leftColumnName = (Column) leftExpression;
|
||||
columnName = leftColumnName.getColumnName();
|
||||
}
|
||||
if (leftExpression instanceof Function) {
|
||||
Function function = (Function) leftExpression;
|
||||
columnName = ((Column) function.getParameters().getExpressions().get(0)).getColumnName();
|
||||
}
|
||||
String columnName = SqlParserSelectHelper.getColumnName(leftExpression);
|
||||
if (StringUtils.isEmpty(columnName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> valueMap = new HashMap<>();
|
||||
for (String key : filedNameToValueMap.keySet()) {
|
||||
if (columnName.contains(key)) {
|
||||
valueMap = filedNameToValueMap.get(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//filedNameToValueMap.get(columnName);
|
||||
Map<String, String> valueMap = filedNameToValueMap.get(columnName);
|
||||
if (Objects.isNull(valueMap) || valueMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.Function;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
import net.sf.jsqlparser.expression.Parenthesis;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator;
|
||||
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import net.sf.jsqlparser.statement.select.GroupByElement;
|
||||
import net.sf.jsqlparser.statement.select.OrderByElement;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectBody;
|
||||
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
|
||||
import net.sf.jsqlparser.util.SelectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Sql Parser add Helper
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlParserAddHelper {
|
||||
|
||||
public static String addFieldsToSelect(String sql, List<String> fields) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
// add fields to select
|
||||
for (String field : fields) {
|
||||
SelectUtils.addExpression(selectStatement, new Column(field));
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addFunctionToSelect(String sql, Expression expression) {
|
||||
PlainSelect plainSelect = SqlParserSelectHelper.getPlainSelect(sql);
|
||||
if (Objects.isNull(plainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<SelectItem> selectItems = plainSelect.getSelectItems();
|
||||
if (CollectionUtils.isEmpty(selectItems)) {
|
||||
return sql;
|
||||
}
|
||||
boolean existFunction = false;
|
||||
for (SelectItem selectItem : selectItems) {
|
||||
SelectExpressionItem expressionItem = (SelectExpressionItem) selectItem;
|
||||
if (expressionItem.getExpression() instanceof Function) {
|
||||
Function expressionFunction = (Function) expressionItem.getExpression();
|
||||
if (expression.toString().equalsIgnoreCase(expressionFunction.toString())) {
|
||||
existFunction = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!existFunction) {
|
||||
SelectExpressionItem sumExpressionItem = new SelectExpressionItem(expression);
|
||||
selectItems.add(sumExpressionItem);
|
||||
}
|
||||
return plainSelect.toString();
|
||||
}
|
||||
|
||||
public static String addWhere(String sql, String column, Object value) {
|
||||
if (StringUtils.isEmpty(column) || Objects.isNull(value)) {
|
||||
return sql;
|
||||
}
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
|
||||
Expression right = new StringValue(value.toString());
|
||||
if (value instanceof Integer || value instanceof Long) {
|
||||
right = new LongValue(value.toString());
|
||||
}
|
||||
|
||||
if (where == null) {
|
||||
plainSelect.setWhere(new EqualsTo(new Column(column), right));
|
||||
} else {
|
||||
plainSelect.setWhere(new AndExpression(where, new EqualsTo(new Column(column), right)));
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String addWhere(String sql, Expression expression) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
|
||||
if (where == null) {
|
||||
plainSelect.setWhere(expression);
|
||||
} else {
|
||||
plainSelect.setWhere(new AndExpression(where, expression));
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addAggregateToField(String sql, Map<String, String> fieldNameToAggregate) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
selectBody.accept(new SelectVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
addAggregateToSelectItems(plainSelect.getSelectItems(), fieldNameToAggregate);
|
||||
addAggregateToOrderByItems(plainSelect.getOrderByElements(), fieldNameToAggregate);
|
||||
addAggregateToGroupByItems(plainSelect.getGroupBy(), fieldNameToAggregate);
|
||||
addAggregateToWhereItems(plainSelect.getWhere(), fieldNameToAggregate);
|
||||
}
|
||||
});
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addGroupBy(String sql, Set<String> groupByFields) {
|
||||
if (CollectionUtils.isEmpty(groupByFields)) {
|
||||
return sql;
|
||||
}
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
GroupByElement groupByElement = new GroupByElement();
|
||||
List<String> originalGroupByFields = SqlParserSelectHelper.getGroupByFields(sql);
|
||||
if (!CollectionUtils.isEmpty(originalGroupByFields)) {
|
||||
groupByFields.addAll(originalGroupByFields);
|
||||
}
|
||||
for (String groupByField : groupByFields) {
|
||||
groupByElement.addGroupByExpression(new Column(groupByField));
|
||||
}
|
||||
plainSelect.setGroupByElement(groupByElement);
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static void addAggregateToSelectItems(List<SelectItem> selectItems,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
for (SelectItem selectItem : selectItems) {
|
||||
if (selectItem instanceof SelectExpressionItem) {
|
||||
SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
|
||||
Expression expression = selectExpressionItem.getExpression();
|
||||
Function function = SqlParserSelectFunctionHelper.getFunction(expression, fieldNameToAggregate);
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
selectExpressionItem.setExpression(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAggregateToOrderByItems(List<OrderByElement> orderByElements,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
if (orderByElements == null) {
|
||||
return;
|
||||
}
|
||||
for (OrderByElement orderByElement : orderByElements) {
|
||||
Expression expression = orderByElement.getExpression();
|
||||
Function function = SqlParserSelectFunctionHelper.getFunction(expression, fieldNameToAggregate);
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
orderByElement.setExpression(function);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAggregateToGroupByItems(GroupByElement groupByElement,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
if (groupByElement == null) {
|
||||
return;
|
||||
}
|
||||
for (Expression expression : groupByElement.getGroupByExpressions()) {
|
||||
Function function = SqlParserSelectFunctionHelper.getFunction(expression, fieldNameToAggregate);
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
groupByElement.addGroupByExpression(function);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAggregateToWhereItems(Expression whereExpression, Map<String, String> fieldNameToAggregate) {
|
||||
if (whereExpression == null) {
|
||||
return;
|
||||
}
|
||||
modifyWhereExpression(whereExpression, fieldNameToAggregate);
|
||||
}
|
||||
|
||||
private static void modifyWhereExpression(Expression whereExpression,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
if (SqlParserSelectHelper.isLogicExpression(whereExpression)) {
|
||||
AndExpression andExpression = (AndExpression) whereExpression;
|
||||
Expression leftExpression = andExpression.getLeftExpression();
|
||||
Expression rightExpression = andExpression.getRightExpression();
|
||||
modifyWhereExpression(leftExpression, fieldNameToAggregate);
|
||||
modifyWhereExpression(rightExpression, fieldNameToAggregate);
|
||||
} else if (whereExpression instanceof Parenthesis) {
|
||||
modifyWhereExpression(((Parenthesis) whereExpression).getExpression(), fieldNameToAggregate);
|
||||
} else {
|
||||
setAggToFunction(whereExpression, fieldNameToAggregate);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setAggToFunction(Expression expression, Map<String, String> fieldNameToAggregate) {
|
||||
if (!(expression instanceof ComparisonOperator)) {
|
||||
return;
|
||||
}
|
||||
ComparisonOperator comparisonOperator = (ComparisonOperator) expression;
|
||||
if (comparisonOperator.getRightExpression() instanceof Column) {
|
||||
String columnName = ((Column) (comparisonOperator).getRightExpression()).getColumnName();
|
||||
Function function = SqlParserSelectFunctionHelper.getFunction(comparisonOperator.getRightExpression(),
|
||||
fieldNameToAggregate.get(columnName));
|
||||
if (Objects.nonNull(function)) {
|
||||
comparisonOperator.setRightExpression(function);
|
||||
}
|
||||
}
|
||||
if (comparisonOperator.getLeftExpression() instanceof Column) {
|
||||
String columnName = ((Column) (comparisonOperator).getLeftExpression()).getColumnName();
|
||||
Function function = SqlParserSelectFunctionHelper.getFunction(comparisonOperator.getLeftExpression(),
|
||||
fieldNameToAggregate.get(columnName));
|
||||
if (Objects.nonNull(function)) {
|
||||
comparisonOperator.setLeftExpression(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String addHaving(String sql, Set<String> fieldNames) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
//replace metric to 1 and 1 and add having metric
|
||||
Expression where = plainSelect.getWhere();
|
||||
FiledFilterReplaceVisitor visitor = new FiledFilterReplaceVisitor(fieldNames);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
List<Expression> waitingForAdds = visitor.getWaitingForAdds();
|
||||
if (!CollectionUtils.isEmpty(waitingForAdds)) {
|
||||
for (Expression waitingForAdd : waitingForAdds) {
|
||||
Expression having = plainSelect.getHaving();
|
||||
if (Objects.isNull(having)) {
|
||||
plainSelect.setHaving(waitingForAdd);
|
||||
} else {
|
||||
plainSelect.setHaving(new AndExpression(having, waitingForAdd));
|
||||
}
|
||||
}
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addParenthesisToWhere(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
if (Objects.nonNull(where)) {
|
||||
Parenthesis parenthesis = new Parenthesis(where);
|
||||
plainSelect.setWhere(parenthesis);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.Parenthesis;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator;
|
||||
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
|
||||
import net.sf.jsqlparser.expression.operators.relational.InExpression;
|
||||
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.SelectBody;
|
||||
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
|
||||
|
||||
/**
|
||||
* Sql Parser remove Helper
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlParserRemoveHelper {
|
||||
|
||||
public static String removeWhereCondition(String sql, Set<String> removeFieldNames) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
selectBody.accept(new SelectVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
removeWhereCondition(plainSelect.getWhere(), removeFieldNames);
|
||||
}
|
||||
});
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static void removeWhereCondition(Expression whereExpression, Set<String> removeFieldNames) {
|
||||
if (whereExpression == null) {
|
||||
return;
|
||||
}
|
||||
removeWhereExpression(whereExpression, removeFieldNames);
|
||||
}
|
||||
|
||||
private static void removeWhereExpression(Expression whereExpression, Set<String> removeFieldNames) {
|
||||
if (SqlParserSelectHelper.isLogicExpression(whereExpression)) {
|
||||
AndExpression andExpression = (AndExpression) whereExpression;
|
||||
Expression leftExpression = andExpression.getLeftExpression();
|
||||
Expression rightExpression = andExpression.getRightExpression();
|
||||
|
||||
removeWhereExpression(leftExpression, removeFieldNames);
|
||||
removeWhereExpression(rightExpression, removeFieldNames);
|
||||
} else if (whereExpression instanceof Parenthesis) {
|
||||
removeWhereExpression(((Parenthesis) whereExpression).getExpression(), removeFieldNames);
|
||||
} else {
|
||||
removeExpressionWithConstant(whereExpression, removeFieldNames);
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeExpressionWithConstant(Expression expression, Set<String> removeFieldNames) {
|
||||
if (expression instanceof EqualsTo) {
|
||||
ComparisonOperator comparisonOperator = (ComparisonOperator) expression;
|
||||
String columnName = SqlParserSelectHelper.getColumnName(comparisonOperator.getLeftExpression(),
|
||||
comparisonOperator.getRightExpression());
|
||||
if (!removeFieldNames.contains(columnName)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ComparisonOperator constantExpression = (ComparisonOperator) CCJSqlParserUtil.parseCondExpression(
|
||||
JsqlConstants.EQUAL_CONSTANT);
|
||||
comparisonOperator.setLeftExpression(constantExpression.getLeftExpression());
|
||||
comparisonOperator.setRightExpression(constantExpression.getRightExpression());
|
||||
comparisonOperator.setASTNode(constantExpression.getASTNode());
|
||||
} catch (JSQLParserException e) {
|
||||
log.error("JSQLParserException", e);
|
||||
}
|
||||
}
|
||||
if (expression instanceof InExpression) {
|
||||
InExpression inExpression = (InExpression) expression;
|
||||
String columnName = SqlParserSelectHelper.getColumnName(inExpression.getLeftExpression(),
|
||||
inExpression.getRightExpression());
|
||||
if (!removeFieldNames.contains(columnName)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
InExpression constantExpression = (InExpression) CCJSqlParserUtil.parseCondExpression(
|
||||
JsqlConstants.IN_CONSTANT);
|
||||
inExpression.setLeftExpression(constantExpression.getLeftExpression());
|
||||
inExpression.setRightItemsList(constantExpression.getRightItemsList());
|
||||
inExpression.setASTNode(constantExpression.getASTNode());
|
||||
} catch (JSQLParserException e) {
|
||||
log.error("JSQLParserException", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.statement.select.GroupByElement;
|
||||
import net.sf.jsqlparser.statement.select.OrderByElement;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectBody;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Sql Parser replace Helper
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlParserReplaceHelper {
|
||||
|
||||
public static String replaceValue(String sql, Map<String, Map<String, String>> filedNameToValueMap) {
|
||||
return replaceValue(sql, filedNameToValueMap, true);
|
||||
}
|
||||
|
||||
public static String replaceValue(String sql, Map<String, Map<String, String>> filedNameToValueMap,
|
||||
boolean exactReplace) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<PlainSelect> plainSelects = SqlParserSelectHelper.getPlainSelects((PlainSelect) selectBody);
|
||||
for (PlainSelect plainSelect : plainSelects) {
|
||||
Expression where = plainSelect.getWhere();
|
||||
FieldlValueReplaceVisitor visitor = new FieldlValueReplaceVisitor(exactReplace, filedNameToValueMap);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceFieldNameByValue(String sql, Map<String, Set<String>> fieldValueToFieldNames) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<PlainSelect> plainSelects = SqlParserSelectHelper.getPlainSelects((PlainSelect) selectBody);
|
||||
for (PlainSelect plainSelect : plainSelects) {
|
||||
Expression where = plainSelect.getWhere();
|
||||
FiledNameReplaceVisitor visitor = new FiledNameReplaceVisitor(fieldValueToFieldNames);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceFields(String sql, Map<String, String> fieldNameMap) {
|
||||
return replaceFields(sql, fieldNameMap, false);
|
||||
}
|
||||
|
||||
public static String replaceFields(String sql, Map<String, String> fieldNameMap, boolean exactReplace) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<PlainSelect> plainSelects = SqlParserSelectHelper.getPlainSelects((PlainSelect) selectBody);
|
||||
for (PlainSelect plainSelect : plainSelects) {
|
||||
replaceFieldsInPlainOneSelect(fieldNameMap, exactReplace, plainSelect);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static void replaceFieldsInPlainOneSelect(Map<String, String> fieldNameMap, boolean exactReplace,
|
||||
PlainSelect plainSelect) {
|
||||
//1. replace where fields
|
||||
Expression where = plainSelect.getWhere();
|
||||
FieldReplaceVisitor visitor = new FieldReplaceVisitor(fieldNameMap, exactReplace);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
|
||||
//2. replace select fields
|
||||
for (SelectItem selectItem : plainSelect.getSelectItems()) {
|
||||
selectItem.accept(visitor);
|
||||
}
|
||||
|
||||
//3. replace oder by fields
|
||||
List<OrderByElement> orderByElements = plainSelect.getOrderByElements();
|
||||
if (!CollectionUtils.isEmpty(orderByElements)) {
|
||||
for (OrderByElement orderByElement : orderByElements) {
|
||||
orderByElement.accept(new OrderByReplaceVisitor(fieldNameMap, exactReplace));
|
||||
}
|
||||
}
|
||||
//4. replace group by fields
|
||||
GroupByElement groupByElement = plainSelect.getGroupBy();
|
||||
if (Objects.nonNull(groupByElement)) {
|
||||
groupByElement.accept(new GroupByReplaceVisitor(fieldNameMap, exactReplace));
|
||||
}
|
||||
//5. replace having fields
|
||||
Expression having = plainSelect.getHaving();
|
||||
if (Objects.nonNull(having)) {
|
||||
having.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
public static String replaceFunction(String sql, Map<String, String> functionMap) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<PlainSelect> plainSelects = SqlParserSelectHelper.getPlainSelects((PlainSelect) selectBody);
|
||||
for (PlainSelect plainSelect : plainSelects) {
|
||||
replaceFunction(functionMap, plainSelect);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static void replaceFunction(Map<String, String> functionMap, PlainSelect selectBody) {
|
||||
PlainSelect plainSelect = selectBody;
|
||||
//1. replace where dataDiff function
|
||||
Expression where = plainSelect.getWhere();
|
||||
|
||||
FunctionNameReplaceVisitor visitor = new FunctionNameReplaceVisitor(functionMap);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
GroupByElement groupBy = plainSelect.getGroupBy();
|
||||
if (Objects.nonNull(groupBy)) {
|
||||
GroupByFunctionReplaceVisitor replaceVisitor = new GroupByFunctionReplaceVisitor(functionMap);
|
||||
groupBy.accept(replaceVisitor);
|
||||
}
|
||||
|
||||
for (SelectItem selectItem : plainSelect.getSelectItems()) {
|
||||
selectItem.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
public static String replaceFunction(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<PlainSelect> plainSelects = SqlParserSelectHelper.getPlainSelects((PlainSelect) selectBody);
|
||||
for (PlainSelect plainSelect : plainSelects) {
|
||||
replaceFunction(plainSelect);
|
||||
}
|
||||
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 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;
|
||||
}
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
// replace table name
|
||||
List<PlainSelect> painSelects = SqlParserSelectHelper.getPlainSelects(plainSelect);
|
||||
for (PlainSelect painSelect : painSelects) {
|
||||
painSelect.accept(
|
||||
new SelectVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
plainSelect.getFromItem().accept(new TableNameReplaceVisitor(tableName));
|
||||
}
|
||||
});
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceAlias(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
FunctionAliasReplaceVisitor visitor = new FunctionAliasReplaceVisitor();
|
||||
for (SelectItem selectItem : plainSelect.getSelectItems()) {
|
||||
selectItem.accept(visitor);
|
||||
}
|
||||
Map<String, String> aliasToActualExpression = visitor.getAliasToActualExpression();
|
||||
if (Objects.nonNull(aliasToActualExpression) && !aliasToActualExpression.isEmpty()) {
|
||||
return replaceFields(selectStatement.toString(), aliasToActualExpression, true);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceHavingValue(String sql, Map<String, Map<String, String>> filedNameToValueMap) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression having = plainSelect.getHaving();
|
||||
FieldlValueReplaceVisitor visitor = new FieldlValueReplaceVisitor(false, filedNameToValueMap);
|
||||
if (Objects.nonNull(having)) {
|
||||
having.accept(visitor);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.Function;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectBody;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Sql Parser Select function Helper
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlParserSelectFunctionHelper {
|
||||
|
||||
public static boolean hasAggregateFunction(String sql) {
|
||||
if (hasFunction(sql)) {
|
||||
return true;
|
||||
}
|
||||
return SqlParserSelectHelper.hasGroupBy(sql);
|
||||
}
|
||||
|
||||
public static boolean hasFunction(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return false;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
List<SelectItem> selectItems = plainSelect.getSelectItems();
|
||||
AggregateFunctionVisitor visitor = new AggregateFunctionVisitor();
|
||||
for (SelectItem selectItem : selectItems) {
|
||||
selectItem.accept(visitor);
|
||||
}
|
||||
boolean selectFunction = visitor.hasAggregateFunction();
|
||||
if (selectFunction) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Function getFunction(Expression expression, Map<String, String> fieldNameToAggregate) {
|
||||
if (!(expression instanceof Column)) {
|
||||
return null;
|
||||
}
|
||||
String columnName = ((Column) expression).getColumnName();
|
||||
if (StringUtils.isEmpty(columnName)) {
|
||||
return null;
|
||||
}
|
||||
Function function = getFunction(expression, fieldNameToAggregate.get(columnName));
|
||||
if (Objects.isNull(function)) {
|
||||
return null;
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
public static Function getFunction(Expression expression, String aggregateName) {
|
||||
if (StringUtils.isEmpty(aggregateName)) {
|
||||
return null;
|
||||
}
|
||||
Function sumFunction = new Function();
|
||||
sumFunction.setName(aggregateName);
|
||||
sumFunction.setParameters(new ExpressionList(expression));
|
||||
return sumFunction;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,11 @@ import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
@@ -21,6 +25,8 @@ import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectBody;
|
||||
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
|
||||
import net.sf.jsqlparser.statement.select.SubSelect;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
@@ -109,6 +115,28 @@ public class SqlParserSelectHelper {
|
||||
return (Select) statement;
|
||||
}
|
||||
|
||||
public static List<PlainSelect> getPlainSelects(PlainSelect plainSelect) {
|
||||
List<PlainSelect> plainSelects = new ArrayList<>();
|
||||
plainSelects.add(plainSelect);
|
||||
plainSelect.accept(new SelectVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
Expression whereExpression = plainSelect.getWhere();
|
||||
if (whereExpression != null) {
|
||||
whereExpression.accept(new ExpressionVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(SubSelect subSelect) {
|
||||
SelectBody subSelectBody = subSelect.getSelectBody();
|
||||
if (subSelectBody instanceof PlainSelect) {
|
||||
plainSelects.add((PlainSelect) subSelectBody);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return plainSelects;
|
||||
}
|
||||
|
||||
public static List<String> getAllFields(String sql) {
|
||||
|
||||
@@ -244,14 +272,6 @@ public class SqlParserSelectHelper {
|
||||
return new ArrayList<>(result);
|
||||
}
|
||||
|
||||
|
||||
public static boolean hasAggregateFunction(String sql) {
|
||||
if (hasFunction(sql)) {
|
||||
return true;
|
||||
}
|
||||
return hasGroupBy(sql);
|
||||
}
|
||||
|
||||
public static boolean hasGroupBy(String sql) {
|
||||
Select selectStatement = getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
@@ -269,24 +289,36 @@ public class SqlParserSelectHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasFunction(String sql) {
|
||||
Select selectStatement = getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
public static boolean isLogicExpression(Expression whereExpression) {
|
||||
return whereExpression instanceof AndExpression || (whereExpression instanceof OrExpression
|
||||
|| (whereExpression instanceof XorExpression));
|
||||
}
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return false;
|
||||
public static String getColumnName(Expression leftExpression, Expression rightExpression) {
|
||||
if (leftExpression instanceof Column) {
|
||||
return ((Column) leftExpression).getColumnName();
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
List<SelectItem> selectItems = plainSelect.getSelectItems();
|
||||
AggregateFunctionVisitor visitor = new AggregateFunctionVisitor();
|
||||
for (SelectItem selectItem : selectItems) {
|
||||
selectItem.accept(visitor);
|
||||
if (rightExpression instanceof Column) {
|
||||
return ((Column) rightExpression).getColumnName();
|
||||
}
|
||||
boolean selectFunction = visitor.hasAggregateFunction();
|
||||
if (selectFunction) {
|
||||
return true;
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getColumnName(Expression leftExpression) {
|
||||
if (leftExpression instanceof Column) {
|
||||
Column leftColumnName = (Column) leftExpression;
|
||||
return leftColumnName.getColumnName();
|
||||
}
|
||||
return false;
|
||||
if (leftExpression instanceof Function) {
|
||||
Function function = (Function) leftExpression;
|
||||
if (!CollectionUtils.isEmpty(function.getParameters().getExpressions())) {
|
||||
Expression expression = function.getParameters().getExpressions().get(0);
|
||||
if (expression instanceof Column) {
|
||||
return ((Column) expression).getColumnName();
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,604 +0,0 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.Parenthesis;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator;
|
||||
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
|
||||
import net.sf.jsqlparser.expression.operators.relational.InExpression;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import net.sf.jsqlparser.schema.Table;
|
||||
import net.sf.jsqlparser.statement.select.GroupByElement;
|
||||
import net.sf.jsqlparser.statement.select.OrderByElement;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectBody;
|
||||
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
|
||||
import net.sf.jsqlparser.util.SelectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Sql Parser Update Helper
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlParserUpdateHelper {
|
||||
|
||||
public static String replaceValue(String sql, Map<String, Map<String, String>> filedNameToValueMap) {
|
||||
return replaceValue(sql, filedNameToValueMap, true);
|
||||
}
|
||||
|
||||
public static String replaceValue(String sql, Map<String, Map<String, String>> filedNameToValueMap,
|
||||
boolean exactReplace) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
FieldlValueReplaceVisitor visitor = new FieldlValueReplaceVisitor(exactReplace, filedNameToValueMap);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceHavingValue(String sql, Map<String, Map<String, String>> filedNameToValueMap) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression having = plainSelect.getHaving();
|
||||
FieldlValueReplaceVisitor visitor = new FieldlValueReplaceVisitor(false, filedNameToValueMap);
|
||||
if (Objects.nonNull(having)) {
|
||||
having.accept(visitor);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceFieldNameByValue(String sql, Map<String, Set<String>> fieldValueToFieldNames) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
FiledNameReplaceVisitor visitor = new FiledNameReplaceVisitor(fieldValueToFieldNames);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceFields(String sql, Map<String, String> fieldNameMap) {
|
||||
return replaceFields(sql, fieldNameMap, false);
|
||||
}
|
||||
|
||||
public static String replaceFields(String sql, Map<String, String> fieldNameMap, boolean exactReplace) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
//1. replace where fields
|
||||
Expression where = plainSelect.getWhere();
|
||||
FieldReplaceVisitor visitor = new FieldReplaceVisitor(fieldNameMap, exactReplace);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
|
||||
//2. replace select fields
|
||||
for (SelectItem selectItem : plainSelect.getSelectItems()) {
|
||||
selectItem.accept(visitor);
|
||||
}
|
||||
|
||||
//3. replace oder by fields
|
||||
List<OrderByElement> orderByElements = plainSelect.getOrderByElements();
|
||||
if (!CollectionUtils.isEmpty(orderByElements)) {
|
||||
for (OrderByElement orderByElement : orderByElements) {
|
||||
orderByElement.accept(new OrderByReplaceVisitor(fieldNameMap, exactReplace));
|
||||
}
|
||||
}
|
||||
|
||||
//4. replace group by fields
|
||||
GroupByElement groupByElement = plainSelect.getGroupBy();
|
||||
if (Objects.nonNull(groupByElement)) {
|
||||
groupByElement.accept(new GroupByReplaceVisitor(fieldNameMap, exactReplace));
|
||||
}
|
||||
//5. replace having fields
|
||||
Expression having = plainSelect.getHaving();
|
||||
if (Objects.nonNull(having)) {
|
||||
having.accept(visitor);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceFunction(String sql, Map<String, String> functionMap) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
//1. replace where dataDiff function
|
||||
Expression where = plainSelect.getWhere();
|
||||
|
||||
FunctionNameReplaceVisitor visitor = new FunctionNameReplaceVisitor(functionMap);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
GroupByElement groupBy = plainSelect.getGroupBy();
|
||||
if (Objects.nonNull(groupBy)) {
|
||||
GroupByFunctionReplaceVisitor replaceVisitor = new GroupByFunctionReplaceVisitor(functionMap);
|
||||
groupBy.accept(replaceVisitor);
|
||||
}
|
||||
|
||||
for (SelectItem selectItem : plainSelect.getSelectItems()) {
|
||||
selectItem.accept(visitor);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String replaceFunction(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect 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);
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
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 addFieldsToSelect(String sql, List<String> fields) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
// add fields to select
|
||||
for (String field : fields) {
|
||||
SelectUtils.addExpression(selectStatement, new Column(field));
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addFunctionToSelect(String sql, Expression expression) {
|
||||
PlainSelect plainSelect = SqlParserSelectHelper.getPlainSelect(sql);
|
||||
if (Objects.isNull(plainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
List<SelectItem> selectItems = plainSelect.getSelectItems();
|
||||
if (CollectionUtils.isEmpty(selectItems)) {
|
||||
return sql;
|
||||
}
|
||||
boolean existFunction = false;
|
||||
for (SelectItem selectItem : selectItems) {
|
||||
SelectExpressionItem expressionItem = (SelectExpressionItem) selectItem;
|
||||
if (expressionItem.getExpression() instanceof Function) {
|
||||
Function expressionFunction = (Function) expressionItem.getExpression();
|
||||
if (expression.toString().equalsIgnoreCase(expressionFunction.toString())) {
|
||||
existFunction = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!existFunction) {
|
||||
SelectExpressionItem sumExpressionItem = new SelectExpressionItem(expression);
|
||||
selectItems.add(sumExpressionItem);
|
||||
}
|
||||
return plainSelect.toString();
|
||||
}
|
||||
|
||||
public static String replaceTable(String sql, String tableName) {
|
||||
if (StringUtils.isEmpty(tableName)) {
|
||||
return sql;
|
||||
}
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
// replace table name
|
||||
Table table = (Table) plainSelect.getFromItem();
|
||||
table.setName(tableName);
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String replaceAlias(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
FunctionAliasReplaceVisitor visitor = new FunctionAliasReplaceVisitor();
|
||||
for (SelectItem selectItem : plainSelect.getSelectItems()) {
|
||||
selectItem.accept(visitor);
|
||||
}
|
||||
Map<String, String> aliasToActualExpression = visitor.getAliasToActualExpression();
|
||||
if (Objects.nonNull(aliasToActualExpression) && !aliasToActualExpression.isEmpty()) {
|
||||
return replaceFields(selectStatement.toString(), aliasToActualExpression, true);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addWhere(String sql, String column, Object value) {
|
||||
if (StringUtils.isEmpty(column) || Objects.isNull(value)) {
|
||||
return sql;
|
||||
}
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
|
||||
Expression right = new StringValue(value.toString());
|
||||
if (value instanceof Integer || value instanceof Long) {
|
||||
right = new LongValue(value.toString());
|
||||
}
|
||||
|
||||
if (where == null) {
|
||||
plainSelect.setWhere(new EqualsTo(new Column(column), right));
|
||||
} else {
|
||||
plainSelect.setWhere(new AndExpression(where, new EqualsTo(new Column(column), right)));
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String addWhere(String sql, Expression expression) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
|
||||
if (where == null) {
|
||||
plainSelect.setWhere(expression);
|
||||
} else {
|
||||
plainSelect.setWhere(new AndExpression(where, expression));
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addAggregateToField(String sql, Map<String, String> fieldNameToAggregate) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
selectBody.accept(new SelectVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
addAggregateToSelectItems(plainSelect.getSelectItems(), fieldNameToAggregate);
|
||||
addAggregateToOrderByItems(plainSelect.getOrderByElements(), fieldNameToAggregate);
|
||||
addAggregateToGroupByItems(plainSelect.getGroupBy(), fieldNameToAggregate);
|
||||
addAggregateToWhereItems(plainSelect.getWhere(), fieldNameToAggregate);
|
||||
}
|
||||
});
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String addGroupBy(String sql, Set<String> groupByFields) {
|
||||
if (CollectionUtils.isEmpty(groupByFields)) {
|
||||
return sql;
|
||||
}
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
GroupByElement groupByElement = new GroupByElement();
|
||||
List<String> originalGroupByFields = SqlParserSelectHelper.getGroupByFields(sql);
|
||||
if (!CollectionUtils.isEmpty(originalGroupByFields)) {
|
||||
groupByFields.addAll(originalGroupByFields);
|
||||
}
|
||||
for (String groupByField : groupByFields) {
|
||||
groupByElement.addGroupByExpression(new Column(groupByField));
|
||||
}
|
||||
plainSelect.setGroupByElement(groupByElement);
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static void addAggregateToSelectItems(List<SelectItem> selectItems,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
for (SelectItem selectItem : selectItems) {
|
||||
if (selectItem instanceof SelectExpressionItem) {
|
||||
SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
|
||||
Expression expression = selectExpressionItem.getExpression();
|
||||
Function function = getFunction(expression, fieldNameToAggregate);
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
selectExpressionItem.setExpression(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAggregateToOrderByItems(List<OrderByElement> orderByElements,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
if (orderByElements == null) {
|
||||
return;
|
||||
}
|
||||
for (OrderByElement orderByElement : orderByElements) {
|
||||
Expression expression = orderByElement.getExpression();
|
||||
Function function = getFunction(expression, fieldNameToAggregate);
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
orderByElement.setExpression(function);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAggregateToGroupByItems(GroupByElement groupByElement,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
if (groupByElement == null) {
|
||||
return;
|
||||
}
|
||||
for (Expression expression : groupByElement.getGroupByExpressions()) {
|
||||
Function function = getFunction(expression, fieldNameToAggregate);
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
groupByElement.addGroupByExpression(function);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAggregateToWhereItems(Expression whereExpression, Map<String, String> fieldNameToAggregate) {
|
||||
if (whereExpression == null) {
|
||||
return;
|
||||
}
|
||||
modifyWhereExpression(whereExpression, fieldNameToAggregate);
|
||||
}
|
||||
|
||||
private static void modifyWhereExpression(Expression whereExpression,
|
||||
Map<String, String> fieldNameToAggregate) {
|
||||
if (isLogicExpression(whereExpression)) {
|
||||
AndExpression andExpression = (AndExpression) whereExpression;
|
||||
Expression leftExpression = andExpression.getLeftExpression();
|
||||
Expression rightExpression = andExpression.getRightExpression();
|
||||
modifyWhereExpression(leftExpression, fieldNameToAggregate);
|
||||
modifyWhereExpression(rightExpression, fieldNameToAggregate);
|
||||
} else if (whereExpression instanceof Parenthesis) {
|
||||
modifyWhereExpression(((Parenthesis) whereExpression).getExpression(), fieldNameToAggregate);
|
||||
} else {
|
||||
setAggToFunction(whereExpression, fieldNameToAggregate);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLogicExpression(Expression whereExpression) {
|
||||
return whereExpression instanceof AndExpression || (whereExpression instanceof OrExpression
|
||||
|| (whereExpression instanceof XorExpression));
|
||||
}
|
||||
|
||||
|
||||
private static void setAggToFunction(Expression expression, Map<String, String> fieldNameToAggregate) {
|
||||
if (!(expression instanceof ComparisonOperator)) {
|
||||
return;
|
||||
}
|
||||
ComparisonOperator comparisonOperator = (ComparisonOperator) expression;
|
||||
if (comparisonOperator.getRightExpression() instanceof Column) {
|
||||
String columnName = ((Column) (comparisonOperator).getRightExpression()).getColumnName();
|
||||
Function function = getFunction(comparisonOperator.getRightExpression(),
|
||||
fieldNameToAggregate.get(columnName));
|
||||
if (Objects.nonNull(function)) {
|
||||
comparisonOperator.setRightExpression(function);
|
||||
}
|
||||
}
|
||||
if (comparisonOperator.getLeftExpression() instanceof Column) {
|
||||
String columnName = ((Column) (comparisonOperator).getLeftExpression()).getColumnName();
|
||||
Function function = getFunction(comparisonOperator.getLeftExpression(),
|
||||
fieldNameToAggregate.get(columnName));
|
||||
if (Objects.nonNull(function)) {
|
||||
comparisonOperator.setLeftExpression(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Function getFunction(Expression expression, Map<String, String> fieldNameToAggregate) {
|
||||
if (!(expression instanceof Column)) {
|
||||
return null;
|
||||
}
|
||||
String columnName = ((Column) expression).getColumnName();
|
||||
if (StringUtils.isEmpty(columnName)) {
|
||||
return null;
|
||||
}
|
||||
Function function = getFunction(expression, fieldNameToAggregate.get(columnName));
|
||||
if (Objects.isNull(function)) {
|
||||
return null;
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
private static Function getFunction(Expression expression, String aggregateName) {
|
||||
if (StringUtils.isEmpty(aggregateName)) {
|
||||
return null;
|
||||
}
|
||||
Function sumFunction = new Function();
|
||||
sumFunction.setName(aggregateName);
|
||||
sumFunction.setParameters(new ExpressionList(expression));
|
||||
return sumFunction;
|
||||
}
|
||||
|
||||
public static String addHaving(String sql, Set<String> fieldNames) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
//replace metric to 1 and 1 and add having metric
|
||||
Expression where = plainSelect.getWhere();
|
||||
FiledFilterReplaceVisitor visitor = new FiledFilterReplaceVisitor(fieldNames);
|
||||
if (Objects.nonNull(where)) {
|
||||
where.accept(visitor);
|
||||
}
|
||||
List<Expression> waitingForAdds = visitor.getWaitingForAdds();
|
||||
if (!CollectionUtils.isEmpty(waitingForAdds)) {
|
||||
for (Expression waitingForAdd : waitingForAdds) {
|
||||
Expression having = plainSelect.getHaving();
|
||||
if (Objects.isNull(having)) {
|
||||
plainSelect.setHaving(waitingForAdd);
|
||||
} else {
|
||||
plainSelect.setHaving(new AndExpression(having, waitingForAdd));
|
||||
}
|
||||
}
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
public static String removeWhereCondition(String sql, Set<String> removeFieldNames) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
selectBody.accept(new SelectVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
removeWhereCondition(plainSelect.getWhere(), removeFieldNames);
|
||||
}
|
||||
});
|
||||
return selectStatement.toString();
|
||||
}
|
||||
|
||||
private static void removeWhereCondition(Expression whereExpression, Set<String> removeFieldNames) {
|
||||
if (whereExpression == null) {
|
||||
return;
|
||||
}
|
||||
removeWhereExpression(whereExpression, removeFieldNames);
|
||||
}
|
||||
|
||||
private static void removeWhereExpression(Expression whereExpression, Set<String> removeFieldNames) {
|
||||
if (isLogicExpression(whereExpression)) {
|
||||
AndExpression andExpression = (AndExpression) whereExpression;
|
||||
Expression leftExpression = andExpression.getLeftExpression();
|
||||
Expression rightExpression = andExpression.getRightExpression();
|
||||
|
||||
removeWhereExpression(leftExpression, removeFieldNames);
|
||||
removeWhereExpression(rightExpression, removeFieldNames);
|
||||
} else if (whereExpression instanceof Parenthesis) {
|
||||
removeWhereExpression(((Parenthesis) whereExpression).getExpression(), removeFieldNames);
|
||||
} else {
|
||||
removeExpressionWithConstant(whereExpression, removeFieldNames);
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeExpressionWithConstant(Expression expression, Set<String> removeFieldNames) {
|
||||
if (expression instanceof EqualsTo) {
|
||||
ComparisonOperator comparisonOperator = (ComparisonOperator) expression;
|
||||
String columnName = getColumnName(comparisonOperator.getLeftExpression(),
|
||||
comparisonOperator.getRightExpression());
|
||||
if (!removeFieldNames.contains(columnName)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ComparisonOperator constantExpression = (ComparisonOperator) CCJSqlParserUtil.parseCondExpression(
|
||||
JsqlConstants.EQUAL_CONSTANT);
|
||||
comparisonOperator.setLeftExpression(constantExpression.getLeftExpression());
|
||||
comparisonOperator.setRightExpression(constantExpression.getRightExpression());
|
||||
comparisonOperator.setASTNode(constantExpression.getASTNode());
|
||||
} catch (JSQLParserException e) {
|
||||
log.error("JSQLParserException", e);
|
||||
}
|
||||
}
|
||||
if (expression instanceof InExpression) {
|
||||
InExpression inExpression = (InExpression) expression;
|
||||
String columnName = getColumnName(inExpression.getLeftExpression(), inExpression.getRightExpression());
|
||||
if (!removeFieldNames.contains(columnName)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
InExpression constantExpression = (InExpression) CCJSqlParserUtil.parseCondExpression(
|
||||
JsqlConstants.IN_CONSTANT);
|
||||
inExpression.setLeftExpression(constantExpression.getLeftExpression());
|
||||
inExpression.setRightItemsList(constantExpression.getRightItemsList());
|
||||
inExpression.setASTNode(constantExpression.getASTNode());
|
||||
} catch (JSQLParserException e) {
|
||||
log.error("JSQLParserException", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getColumnName(Expression leftExpression, Expression rightExpression) {
|
||||
String columnName = "";
|
||||
if (leftExpression instanceof Column) {
|
||||
columnName = ((Column) leftExpression).getColumnName();
|
||||
}
|
||||
if (rightExpression instanceof Column) {
|
||||
columnName = ((Column) rightExpression).getColumnName();
|
||||
}
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public static String addParenthesisToWhere(String sql) {
|
||||
Select selectStatement = SqlParserSelectHelper.getSelect(sql);
|
||||
SelectBody selectBody = selectStatement.getSelectBody();
|
||||
|
||||
if (!(selectBody instanceof PlainSelect)) {
|
||||
return sql;
|
||||
}
|
||||
PlainSelect plainSelect = (PlainSelect) selectBody;
|
||||
Expression where = plainSelect.getWhere();
|
||||
if (Objects.nonNull(where)) {
|
||||
Parenthesis parenthesis = new Parenthesis(where);
|
||||
plainSelect.setWhere(parenthesis);
|
||||
}
|
||||
return selectStatement.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tencent.supersonic.common.util.jsqlparser;
|
||||
|
||||
import net.sf.jsqlparser.schema.Table;
|
||||
import net.sf.jsqlparser.statement.select.FromItemVisitorAdapter;
|
||||
|
||||
public class TableNameReplaceVisitor extends FromItemVisitorAdapter {
|
||||
|
||||
private String tableName;
|
||||
|
||||
public TableNameReplaceVisitor(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Table table) {
|
||||
table.setName(tableName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user