From 6a36b3fc6af5ae1edd5eed812f42244b81e26de3 Mon Sep 17 00:00:00 2001 From: Andreas Reichel Date: Fri, 5 Jul 2024 12:10:32 +0700 Subject: [PATCH] feat: improve usability of the `ExpressionVisitorAdapter` Signed-off-by: Andreas Reichel --- .../expression/ExpressionVisitorAdapter.java | 368 ++++++++---------- .../expression/LambdaExpression.java | 4 +- 2 files changed, 154 insertions(+), 218 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java index f2223f890..8ade2f5f9 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java @@ -64,6 +64,9 @@ import net.sf.jsqlparser.statement.select.UnPivot; import net.sf.jsqlparser.statement.select.WithItem; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Optional; @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.UncommentedEmptyMethodBody"}) @@ -88,65 +91,58 @@ public T visit(NullValue nullValue, S context) { @Override public T visit(Function function, S context) { + ArrayList subExpressions = new ArrayList<>(); if (function.getParameters() != null) { - function.getParameters().accept(this, context); + subExpressions.addAll(function.getParameters()); } if (function.getKeep() != null) { - function.getKeep().accept(this, context); + subExpressions.add(function.getKeep()); } if (function.getOrderByElements() != null) { for (OrderByElement orderByElement : function.getOrderByElements()) { - orderByElement.getExpression().accept(this, context); + subExpressions.add(orderByElement.getExpression()); } } - return null; + return visitExpressions(function, context, subExpressions); } @Override public T visit(SignedExpression signedExpression, S context) { - signedExpression.getExpression().accept(this, context); - return null; + return signedExpression.getExpression().accept(this, context); } @Override public T visit(JdbcParameter jdbcParameter, S context) { - return null; } @Override public T visit(JdbcNamedParameter jdbcNamedParameter, S context) { - return null; } @Override public T visit(DoubleValue doubleValue, S context) { - return null; } @Override public T visit(LongValue longValue, S context) { - return null; } @Override public T visit(DateValue dateValue, S context) { - return null; } @Override public T visit(TimeValue timeValue, S context) { - return null; } @Override public T visit(TimestampValue timestampValue, S context) { - return null; } @@ -157,171 +153,143 @@ public T visit(StringValue stringValue, S context) { @Override public T visit(Addition addition, S context) { - visitBinaryExpression(addition, context); - return null; + return visitBinaryExpression(addition, context); } @Override public T visit(Division division, S context) { - visitBinaryExpression(division, context); - return null; + return visitBinaryExpression(division, context); } @Override public T visit(IntegerDivision integerDivision, S context) { - visitBinaryExpression(integerDivision, context); - return null; + return visitBinaryExpression(integerDivision, context); } @Override public T visit(Multiplication multiplication, S context) { - visitBinaryExpression(multiplication, context); - return null; + return visitBinaryExpression(multiplication, context); } @Override public T visit(Subtraction subtraction, S context) { - visitBinaryExpression(subtraction, context); - return null; + return visitBinaryExpression(subtraction, context); } @Override public T visit(AndExpression andExpression, S context) { - visitBinaryExpression(andExpression, context); - return null; + return visitBinaryExpression(andExpression, context); } @Override public T visit(OrExpression orExpression, S context) { - visitBinaryExpression(orExpression, context); - return null; + return visitBinaryExpression(orExpression, context); } @Override public T visit(XorExpression xorExpression, S context) { - visitBinaryExpression(xorExpression, context); - return null; + return visitBinaryExpression(xorExpression, context); } @Override public T visit(Between between, S context) { - between.getLeftExpression().accept(this, context); - between.getBetweenExpressionStart().accept(this, context); - between.getBetweenExpressionEnd().accept(this, context); - return null; + return visitExpressions(between, context, between.getLeftExpression(), + between.getBetweenExpressionStart(), between.getBetweenExpressionEnd()); } public T visit(OverlapsCondition overlapsCondition, S context) { - overlapsCondition.getLeft().accept(this, context); - overlapsCondition.getRight().accept(this, context); - return null; + return visitExpressions(overlapsCondition, context, overlapsCondition.getLeft(), + overlapsCondition.getRight()); } @Override public T visit(EqualsTo equalsTo, S context) { - visitBinaryExpression(equalsTo, context); - return null; + return visitBinaryExpression(equalsTo, context); } @Override public T visit(GreaterThan greaterThan, S context) { - visitBinaryExpression(greaterThan, context); - return null; + return visitBinaryExpression(greaterThan, context); } @Override public T visit(GreaterThanEquals greaterThanEquals, S context) { - visitBinaryExpression(greaterThanEquals, context); - return null; + return visitBinaryExpression(greaterThanEquals, context); } @Override public T visit(InExpression inExpression, S context) { - inExpression.getLeftExpression().accept(this, context); - inExpression.getRightExpression().accept(this, context); - return null; + return visitExpressions(inExpression, context, inExpression.getLeftExpression(), + inExpression.getRightExpression()); } @Override public T visit(IncludesExpression includesExpression, S context) { - includesExpression.getLeftExpression().accept(this, context); - includesExpression.getRightExpression().accept(this, context); - return null; + return visitExpressions(includesExpression, context, includesExpression.getLeftExpression(), + includesExpression.getRightExpression()); } @Override public T visit(ExcludesExpression excludesExpression, S context) { - excludesExpression.getLeftExpression().accept(this, context); - excludesExpression.getRightExpression().accept(this, context); - return null; + return visitExpressions(excludesExpression, context, excludesExpression.getLeftExpression(), + excludesExpression.getRightExpression()); } @Override public T visit(IsNullExpression isNullExpression, S context) { - isNullExpression.getLeftExpression().accept(this, context); - return null; + return isNullExpression.getLeftExpression().accept(this, context); } @Override public T visit(FullTextSearch fullTextSearch, S context) { - for (Column col : fullTextSearch.getMatchColumns()) { - col.accept(this, context); - } - return null; + ArrayList subExpressions = new ArrayList<>(fullTextSearch.getMatchColumns()); + subExpressions.add(fullTextSearch.getAgainstValue()); + return visitExpressions(fullTextSearch, context, subExpressions); } @Override public T visit(IsBooleanExpression isBooleanExpression, S context) { - isBooleanExpression.getLeftExpression().accept(this, context); - return null; + return isBooleanExpression.getLeftExpression().accept(this, context); } @Override public T visit(LikeExpression likeExpression, S context) { - visitBinaryExpression(likeExpression, context); - return null; + return visitBinaryExpression(likeExpression, context); } @Override public T visit(MinorThan minorThan, S context) { - visitBinaryExpression(minorThan, context); - return null; + return visitBinaryExpression(minorThan, context); } @Override public T visit(MinorThanEquals minorThanEquals, S context) { - visitBinaryExpression(minorThanEquals, context); - return null; + return visitBinaryExpression(minorThanEquals, context); } @Override public T visit(NotEqualsTo notEqualsTo, S context) { - visitBinaryExpression(notEqualsTo, context); - return null; + return visitBinaryExpression(notEqualsTo, context); } @Override public T visit(DoubleAnd doubleAnd, S context) { - visitBinaryExpression(doubleAnd, context); - return null; + return visitBinaryExpression(doubleAnd, context); } @Override public T visit(Contains contains, S context) { - visitBinaryExpression(contains, context); - return null; + return visitBinaryExpression(contains, context); } @Override public T visit(ContainedBy containedBy, S context) { - visitBinaryExpression(containedBy, context); - return null; + return visitBinaryExpression(containedBy, context); } @Override public T visit(Column column, S context) { - return null; } @@ -336,102 +304,93 @@ public T visit(ParenthesedSelect select, S context) { @Override public T visit(CaseExpression caseExpression, S context) { + ArrayList subExpressions = new ArrayList<>(); + if (caseExpression.getSwitchExpression() != null) { - caseExpression.getSwitchExpression().accept(this, context); - } - for (Expression x : caseExpression.getWhenClauses()) { - x.accept(this, context); + subExpressions.add(caseExpression.getSwitchExpression()); } + subExpressions.addAll(caseExpression.getWhenClauses()); if (caseExpression.getElseExpression() != null) { - caseExpression.getElseExpression().accept(this, context); + subExpressions.add(caseExpression.getElseExpression()); } - return null; + return visitExpressions(caseExpression, context, subExpressions); } @Override public T visit(WhenClause whenClause, S context) { - whenClause.getWhenExpression().accept(this, context); - whenClause.getThenExpression().accept(this, context); - return null; + return visitExpressions(whenClause, context, whenClause.getWhenExpression(), + whenClause.getThenExpression()); } @Override public T visit(ExistsExpression existsExpression, S context) { - existsExpression.getRightExpression().accept(this, context); - return null; + return existsExpression.getRightExpression().accept(this, context); } @Override public T visit(MemberOfExpression memberOfExpression, S context) { - memberOfExpression.getRightExpression().accept(this, context); - return null; + return memberOfExpression.getRightExpression().accept(this, context); } @Override public T visit(AnyComparisonExpression anyComparisonExpression, S context) { - return null; } @Override public T visit(Concat concat, S context) { - visitBinaryExpression(concat, context); - return null; + return visitBinaryExpression(concat, context); } @Override public T visit(Matches matches, S context) { - visitBinaryExpression(matches, context); - return null; + return visitBinaryExpression(matches, context); } @Override public T visit(BitwiseAnd bitwiseAnd, S context) { - visitBinaryExpression(bitwiseAnd, context); - return null; + return visitBinaryExpression(bitwiseAnd, context); } @Override public T visit(BitwiseOr bitwiseOr, S context) { - visitBinaryExpression(bitwiseOr, context); - return null; + return visitBinaryExpression(bitwiseOr, context); } @Override public T visit(BitwiseXor bitwiseXor, S context) { - visitBinaryExpression(bitwiseXor, context); - return null; + return visitBinaryExpression(bitwiseXor, context); } @Override public T visit(CastExpression castExpression, S context) { - castExpression.getLeftExpression().accept(this, context); - return null; + return castExpression.getLeftExpression().accept(this, context); } @Override public T visit(Modulo modulo, S context) { - visitBinaryExpression(modulo, context); - return null; + return visitBinaryExpression(modulo, context); } @Override public T visit(AnalyticExpression analyticExpression, S context) { + ArrayList subExpressions = new ArrayList<>(); + if (analyticExpression.getExpression() != null) { - analyticExpression.getExpression().accept(this, context); + subExpressions.add(analyticExpression.getExpression()); } if (analyticExpression.getDefaultValue() != null) { - analyticExpression.getDefaultValue().accept(this, context); + subExpressions.add(analyticExpression.getDefaultValue()); } if (analyticExpression.getOffset() != null) { - analyticExpression.getOffset().accept(this, context); + subExpressions.add(analyticExpression.getOffset()); } if (analyticExpression.getKeep() != null) { - analyticExpression.getKeep().accept(this, context); + subExpressions.add(analyticExpression.getKeep()); } if (analyticExpression.getFuncOrderBy() != null) { for (OrderByElement element : analyticExpression.getOrderByElements()) { - element.getExpression().accept(this, context); + subExpressions.add(element.getExpression()); } } if (analyticExpression.getWindowElement() != null) { @@ -444,142 +403,144 @@ public T visit(AnalyticExpression analyticExpression, S context) { */ Optional.ofNullable(analyticExpression.getWindowElement().getRange()) .map(WindowRange::getStart) - .map(WindowOffset::getExpression).ifPresent(e -> e.accept(this, context)); + .map(WindowOffset::getExpression).ifPresent(subExpressions::add); Optional.ofNullable(analyticExpression.getWindowElement().getRange()) .map(WindowRange::getEnd) - .map(WindowOffset::getExpression).ifPresent(e -> e.accept(this, context)); + .map(WindowOffset::getExpression).ifPresent(subExpressions::add); Optional.ofNullable(analyticExpression.getWindowElement().getOffset()) - .map(WindowOffset::getExpression).ifPresent(e -> e.accept(this, context)); + .map(WindowOffset::getExpression).ifPresent(subExpressions::add); } - return null; + return visitExpressions(analyticExpression, context, subExpressions); } @Override public T visit(ExtractExpression extractExpression, S context) { - extractExpression.getExpression().accept(this, context); - return null; + return extractExpression.getExpression().accept(this, context); } @Override public T visit(IntervalExpression intervalExpression, S context) { - return null; + return intervalExpression.getExpression().accept(this, context); } @Override public T visit(OracleHierarchicalExpression hierarchicalExpression, S context) { - hierarchicalExpression.getConnectExpression().accept(this, context); - hierarchicalExpression.getStartExpression().accept(this, context); - return null; + return visitExpressions(hierarchicalExpression, context, + hierarchicalExpression.getConnectExpression(), + hierarchicalExpression.getStartExpression()); } @Override public T visit(RegExpMatchOperator regExpMatchOperator, S context) { - visitBinaryExpression(regExpMatchOperator, context); - return null; + return visitBinaryExpression(regExpMatchOperator, context); } @Override public T visit(ExpressionList expressionList, S context) { - for (Expression expr : expressionList) { - expr.accept(this, context); - } - return null; + return visitExpressions(expressionList, context, (Collection) expressionList); } @Override public T visit(RowConstructor rowConstructor, S context) { - for (Expression expr : rowConstructor) { - expr.accept(this, context); - } - return null; + return visitExpressions(rowConstructor, context, (Collection) rowConstructor); } @Override public T visit(NotExpression notExpr, S context) { - notExpr.getExpression().accept(this, context); - return null; + return notExpr.getExpression().accept(this, context); } @Override public T visit(BitwiseRightShift bitwiseRightShift, S context) { - visitBinaryExpression(bitwiseRightShift, context); - return null; + return visitBinaryExpression(bitwiseRightShift, context); } @Override public T visit(BitwiseLeftShift bitwiseLeftShift, S context) { - visitBinaryExpression(bitwiseLeftShift, context); + return visitBinaryExpression(bitwiseLeftShift, context); + } + + protected T visitExpressions(Expression expression, S context, + ExpressionList subExpressions) { + return visitExpressions(expression, context, (Collection) subExpressions); + } + + protected T visitExpressions(Expression expression, S context, + Collection subExpressions) { + for (Expression e : subExpressions) { + if (e != null) { + e.accept(this, context); + } + } return null; } + protected T visitExpressions(Expression expression, S context, + Expression... subExpressions) { + return visitExpressions(expression, context, Arrays.asList(subExpressions)); + } + protected T visitBinaryExpression(BinaryExpression binaryExpression, S context) { - binaryExpression.getLeftExpression().accept(this, context); - binaryExpression.getRightExpression().accept(this, context); - return null; + return visitExpressions(binaryExpression, context, binaryExpression.getLeftExpression(), + binaryExpression.getRightExpression()); } @Override public T visit(JsonExpression jsonExpr, S context) { - jsonExpr.getExpression().accept(this, context); - return null; + return jsonExpr.getExpression().accept(this, context); } @Override public T visit(JsonOperator jsonOperator, S context) { - visitBinaryExpression(jsonOperator, context); - return null; + return visitBinaryExpression(jsonOperator, context); } @Override public T visit(UserVariable userVariable, S context) { - return null; } @Override public T visit(NumericBind numericBind, S context) { - return null; } @Override public T visit(KeepExpression keepExpression, S context) { + ArrayList subExpressions = new ArrayList<>(); for (OrderByElement element : keepExpression.getOrderByElements()) { - element.getExpression().accept(this, context); + subExpressions.add(element.getExpression()); } - return null; + return visitExpressions(keepExpression, context, subExpressions); } @Override public T visit(MySQLGroupConcat groupConcat, S context) { - for (Expression expr : groupConcat.getExpressionList()) { - expr.accept(this, context); - } + ArrayList subExpressions = new ArrayList<>(groupConcat.getExpressionList()); if (groupConcat.getOrderByElements() != null) { for (OrderByElement element : groupConcat.getOrderByElements()) { - element.getExpression().accept(this, context); + subExpressions.add(element.getExpression()); } } - return null; + return visitExpressions(groupConcat, context, subExpressions); } @Override public T visit(Pivot pivot, S context) { for (SelectItem item : pivot.getFunctionItems()) { - item.getExpression().accept(this, context); + item.accept(this, context); } for (Column col : pivot.getForColumns()) { col.accept(this, context); } if (pivot.getSingleInItems() != null) { for (SelectItem item : pivot.getSingleInItems()) { - item.getExpression().accept(this, context); + item.accept(this, context); } } - if (pivot.getMultiInItems() != null) { for (SelectItem> item : pivot.getMultiInItems()) { - item.getExpression().accept(this, context); + item.accept(this, context); } } return null; @@ -588,7 +549,7 @@ public T visit(Pivot pivot, S context) { @Override public T visit(PivotXml pivotXml, S context) { for (SelectItem item : pivotXml.getFunctionItems()) { - item.getExpression().accept(this, context); + item.accept(this, context); } for (Column col : pivotXml.getForColumns()) { col.accept(this, context); @@ -622,37 +583,31 @@ public T visit(AllValue allValue, S context) { @Override public T visit(IsDistinctExpression isDistinctExpression, S context) { - visitBinaryExpression(isDistinctExpression, context); - return null; + return visitBinaryExpression(isDistinctExpression, context); } @Override public T visit(SelectItem selectItem, S context) { - selectItem.getExpression().accept(this, context); - return null; + return selectItem.getExpression().accept(this, context); } @Override public T visit(RowGetExpression rowGetExpression, S context) { - rowGetExpression.getExpression().accept(this, context); - return null; + return rowGetExpression.getExpression().accept(this, context); } @Override public T visit(HexValue hexValue, S context) { - return null; } @Override public T visit(OracleHint hint, S context) { - return null; } @Override public T visit(TimeKeyExpression timeKeyExpression, S context) { - return null; } @@ -668,99 +623,86 @@ public T visit(NextValExpression nextValExpression, S context) { @Override public T visit(CollateExpression collateExpression, S context) { - collateExpression.getLeftExpression().accept(this, context); - return null; + return collateExpression.getLeftExpression().accept(this, context); } @Override public T visit(SimilarToExpression similarToExpression, S context) { - visitBinaryExpression(similarToExpression, context); - return null; + return visitBinaryExpression(similarToExpression, context); } @Override public T visit(ArrayExpression arrayExpression, S context) { - arrayExpression.getObjExpression().accept(this, context); + ArrayList subExpressions = new ArrayList<>(); + + subExpressions.add(arrayExpression.getObjExpression()); if (arrayExpression.getIndexExpression() != null) { - arrayExpression.getIndexExpression().accept(this, context); + subExpressions.add(arrayExpression.getIndexExpression()); } if (arrayExpression.getStartIndexExpression() != null) { - arrayExpression.getStartIndexExpression().accept(this, context); + subExpressions.add(arrayExpression.getStartIndexExpression()); } if (arrayExpression.getStopIndexExpression() != null) { - arrayExpression.getStopIndexExpression().accept(this, context); + subExpressions.add(arrayExpression.getStopIndexExpression()); } - return null; + return visitExpressions(arrayExpression, context, subExpressions); } @Override public T visit(ArrayConstructor arrayConstructor, S context) { - for (Expression expression : arrayConstructor.getExpressions()) { - expression.accept(this, context); - } - return null; + return visitExpressions(arrayConstructor, context, arrayConstructor.getExpressions()); } @Override public T visit(VariableAssignment variableAssignment, S context) { - variableAssignment.getVariable().accept(this, context); - variableAssignment.getExpression().accept(this, context); - return null; + return visitExpressions(variableAssignment, context, variableAssignment.getVariable(), + variableAssignment.getExpression()); } @Override public T visit(XMLSerializeExpr xmlSerializeExpr, S context) { - xmlSerializeExpr.getExpression().accept(this, context); - for (OrderByElement elm : xmlSerializeExpr.getOrderByElements()) { - elm.getExpression().accept(this, context); + ArrayList subExpressions = new ArrayList<>(); + + subExpressions.add(xmlSerializeExpr.getExpression()); + for (OrderByElement orderByElement : xmlSerializeExpr.getOrderByElements()) { + subExpressions.add(orderByElement.getExpression()); } - return null; + return visitExpressions(xmlSerializeExpr, context, subExpressions); } @Override public T visit(TimezoneExpression timezoneExpression, S context) { - timezoneExpression.getLeftExpression().accept(this, context); - return null; + return timezoneExpression.getLeftExpression().accept(this, context); } @Override public T visit(JsonAggregateFunction jsonAggregateFunction, S context) { - Expression expr = jsonAggregateFunction.getExpression(); - if (expr != null) { - expr.accept(this, context); - } - - expr = jsonAggregateFunction.getFilterExpression(); - if (expr != null) { - expr.accept(this, context); - } - return null; + return visitExpressions(jsonAggregateFunction, context, + jsonAggregateFunction.getExpression(), jsonAggregateFunction.getFilterExpression()); } @Override public T visit(JsonFunction jsonFunction, S context) { + ArrayList subExpressions = new ArrayList<>(); for (JsonFunctionExpression expr : jsonFunction.getExpressions()) { - expr.getExpression().accept(this, context); + subExpressions.add(expr.getExpression()); } - return null; + return visitExpressions(jsonFunction, context, subExpressions); } @Override public T visit(ConnectByRootOperator connectByRootOperator, S context) { - connectByRootOperator.getColumn().accept(this, context); - return null; + return connectByRootOperator.getColumn().accept(this, context); } @Override public T visit(OracleNamedFunctionParameter oracleNamedFunctionParameter, S context) { - oracleNamedFunctionParameter.getExpression().accept(this, context); - return null; + return oracleNamedFunctionParameter.getExpression().accept(this, context); } @Override public T visit(GeometryDistance geometryDistance, S context) { - visitBinaryExpression(geometryDistance, context); - return null; + return visitBinaryExpression(geometryDistance, context); } @Override @@ -778,33 +720,28 @@ public T visit(Select select, S context) { @Override public T visit(TranscodingFunction transcodingFunction, S context) { - - return null; + return transcodingFunction.getExpression().accept(this, context); } @Override public T visit(TrimFunction trimFunction, S context) { - - return null; + return trimFunction.getExpression().accept(this, context); } @Override public T visit(RangeExpression rangeExpression, S context) { - rangeExpression.getStartExpression().accept(this, context); - rangeExpression.getEndExpression().accept(this, context); - return null; + return visitExpressions(rangeExpression, context, rangeExpression.getStartExpression(), + rangeExpression.getEndExpression()); } @Override public T visit(TSQLLeftJoin tsqlLeftJoin, S context) { - visitBinaryExpression(tsqlLeftJoin, context); - return null; + return visitBinaryExpression(tsqlLeftJoin, context); } @Override public T visit(TSQLRightJoin tsqlRightJoin, S context) { - visitBinaryExpression(tsqlRightJoin, context); - return null; + return visitBinaryExpression(tsqlRightJoin, context); } @Override @@ -812,7 +749,7 @@ public T visit(StructType structType, S context) { // @todo: visit the ColType also if (structType.getArguments() != null) { for (SelectItem selectItem : structType.getArguments()) { - visit(selectItem, context); + selectItem.accept(this, context); } } return null; @@ -820,8 +757,7 @@ public T visit(StructType structType, S context) { @Override public T visit(LambdaExpression lambdaExpression, S context) { - lambdaExpression.getExpression().accept(this, context); - return null; + return lambdaExpression.getExpression().accept(this, context); } } diff --git a/src/main/java/net/sf/jsqlparser/expression/LambdaExpression.java b/src/main/java/net/sf/jsqlparser/expression/LambdaExpression.java index 46d057f96..78d857287 100644 --- a/src/main/java/net/sf/jsqlparser/expression/LambdaExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/LambdaExpression.java @@ -11,7 +11,7 @@ import net.sf.jsqlparser.parser.ASTNodeAccessImpl; -import java.util.Arrays; +import java.util.Collections; import java.util.List; public class LambdaExpression extends ASTNodeAccessImpl implements Expression { @@ -19,7 +19,7 @@ public class LambdaExpression extends ASTNodeAccessImpl implements Expression { private Expression expression; public LambdaExpression(String identifier, Expression expression) { - this.identifiers = Arrays.asList(identifier); + this.identifiers = Collections.singletonList(identifier); this.expression = expression; }