JSqlParser parses an SQL statement and translate it into a hierarchy of Java classes.
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index 523623eb1..000000000
--- a/settings.gradle
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * This file was generated by the Gradle 'init' task.
- */
-
-rootProject.name = 'jsqlparser'
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 000000000..6765fe187
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,59 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2024 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+module net.sf.jsqlparser {
+ requires java.sql;
+ requires java.logging;
+ requires java.desktop;
+
+ exports net.sf.jsqlparser;
+ exports net.sf.jsqlparser.expression;
+ exports net.sf.jsqlparser.expression.operators.arithmetic;
+ exports net.sf.jsqlparser.expression.operators.conditional;
+ exports net.sf.jsqlparser.expression.operators.relational;
+ exports net.sf.jsqlparser.parser;
+ exports net.sf.jsqlparser.parser.feature;
+ exports net.sf.jsqlparser.schema;
+ exports net.sf.jsqlparser.statement;
+ exports net.sf.jsqlparser.statement.alter;
+ exports net.sf.jsqlparser.statement.alter.sequence;
+ exports net.sf.jsqlparser.statement.analyze;
+ exports net.sf.jsqlparser.statement.comment;
+ exports net.sf.jsqlparser.statement.create.function;
+ exports net.sf.jsqlparser.statement.create.index;
+ exports net.sf.jsqlparser.statement.create.procedure;
+ exports net.sf.jsqlparser.statement.create.schema;
+ exports net.sf.jsqlparser.statement.create.sequence;
+ exports net.sf.jsqlparser.statement.create.synonym;
+ exports net.sf.jsqlparser.statement.create.table;
+ exports net.sf.jsqlparser.statement.create.view;
+ exports net.sf.jsqlparser.statement.delete;
+ exports net.sf.jsqlparser.statement.drop;
+ exports net.sf.jsqlparser.statement.execute;
+ exports net.sf.jsqlparser.statement.export;
+ exports net.sf.jsqlparser.statement.grant;
+ exports net.sf.jsqlparser.statement.imprt;
+ exports net.sf.jsqlparser.statement.insert;
+ exports net.sf.jsqlparser.statement.merge;
+ exports net.sf.jsqlparser.statement.piped;
+ exports net.sf.jsqlparser.statement.refresh;
+ exports net.sf.jsqlparser.statement.select;
+ exports net.sf.jsqlparser.statement.show;
+ exports net.sf.jsqlparser.statement.truncate;
+ exports net.sf.jsqlparser.statement.update;
+ exports net.sf.jsqlparser.statement.upsert;
+ exports net.sf.jsqlparser.util;
+ exports net.sf.jsqlparser.util.cnfexpression;
+ exports net.sf.jsqlparser.util.deparser;
+ exports net.sf.jsqlparser.util.validation;
+ exports net.sf.jsqlparser.util.validation.allowedtypes;
+ exports net.sf.jsqlparser.util.validation.feature;
+ exports net.sf.jsqlparser.util.validation.metadata;
+ exports net.sf.jsqlparser.util.validation.validator;
+}
diff --git a/src/main/java/net/sf/jsqlparser/Model.java b/src/main/java/net/sf/jsqlparser/Model.java
index 3b7378d14..4ad52f429 100644
--- a/src/main/java/net/sf/jsqlparser/Model.java
+++ b/src/main/java/net/sf/jsqlparser/Model.java
@@ -9,10 +9,16 @@
*/
package net.sf.jsqlparser;
+import java.io.Serializable;
+
/**
- * A marker interface for jsqlparser-model-classes.
- * The datastructure where the sql syntax is represented by a tree consists of {@link Model}'s
+ *
+ * A marker interface for jsqlparser-model-classes.
+ *
+ *
+ * The datastructure where the sql syntax is represented by a tree consists of {@link Model}'s
+ *
*/
-public interface Model {
+public interface Model extends Serializable {
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/Alias.java b/src/main/java/net/sf/jsqlparser/expression/Alias.java
index e6718f67a..ffc599680 100644
--- a/src/main/java/net/sf/jsqlparser/expression/Alias.java
+++ b/src/main/java/net/sf/jsqlparser/expression/Alias.java
@@ -9,15 +9,27 @@
*/
package net.sf.jsqlparser.expression;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+
+import net.sf.jsqlparser.schema.MultiPartName;
import net.sf.jsqlparser.statement.create.table.ColDataType;
-public class Alias {
+/**
+ * The type Alias for Tables, Columns or Views.
+ *
+ * We support three different types:
+ * 1) Simple String: `SELECT 1 AS "ALIAS"` when NAME is set and aliasColumns has no elements
+ * 2) UDF Aliases: `SELECT udf(1,2,3) AS "Alias(a,b,c)"` " when NAME!=null and aliasColumns has elements
+ * 3) Column lists for LATERAL VIEW: `SELECT * from a LATERAL VIEW EXPLODE ... AS a, b, c`, when NAME is NULL and aliasColumns has elements
+ * @see Spark LATERAL VIEW
+ */
+public class Alias implements Serializable {
private String name;
private boolean useAs = true;
@@ -36,6 +48,10 @@ public String getName() {
return name;
}
+ public String getUnquotedName() {
+ return MultiPartName.unquote(name);
+ }
+
public void setName(String name) {
this.name = name;
}
@@ -58,20 +74,20 @@ public void setAliasColumns(List aliasColumns) {
@Override
public String toString() {
- String alias = (useAs ? " AS " : " ") + name;
+ String alias = (useAs ? " AS " : " ") + (name != null ? name : "");
if (aliasColumns != null && !aliasColumns.isEmpty()) {
- String ac = "";
+ StringBuilder ac = new StringBuilder();
for (AliasColumn col : aliasColumns) {
if (ac.length() > 0) {
- ac += ", ";
+ ac.append(", ");
}
- ac += col.name;
+ ac.append(col.name);
if (col.colDataType != null) {
- ac += " " + col.colDataType.toString();
+ ac.append(" ").append(col.colDataType);
}
}
- alias += "(" + ac + ")";
+ alias += name != null ? "(" + ac + ")" : ac;
}
return alias;
@@ -92,19 +108,31 @@ public Alias withAliasColumns(List aliasColumns) {
return this;
}
+
+ public Alias addAliasColumns(String... columnNames) {
+ List collection =
+ Optional.ofNullable(getAliasColumns()).orElseGet(ArrayList::new);
+ for (String columnName : columnNames) {
+ collection.add(new AliasColumn(columnName));
+ }
+ return this.withAliasColumns(collection);
+ }
+
public Alias addAliasColumns(AliasColumn... aliasColumns) {
- List collection = Optional.ofNullable(getAliasColumns()).orElseGet(ArrayList::new);
+ List collection =
+ Optional.ofNullable(getAliasColumns()).orElseGet(ArrayList::new);
Collections.addAll(collection, aliasColumns);
return this.withAliasColumns(collection);
}
public Alias addAliasColumns(Collection extends AliasColumn> aliasColumns) {
- List collection = Optional.ofNullable(getAliasColumns()).orElseGet(ArrayList::new);
+ List collection =
+ Optional.ofNullable(getAliasColumns()).orElseGet(ArrayList::new);
collection.addAll(aliasColumns);
return this.withAliasColumns(collection);
}
- public static class AliasColumn {
+ public static class AliasColumn implements Serializable {
public final String name;
public final ColDataType colDataType;
diff --git a/src/main/java/net/sf/jsqlparser/expression/AllValue.java b/src/main/java/net/sf/jsqlparser/expression/AllValue.java
index 39c64fb75..14f924ab8 100644
--- a/src/main/java/net/sf/jsqlparser/expression/AllValue.java
+++ b/src/main/java/net/sf/jsqlparser/expression/AllValue.java
@@ -14,8 +14,8 @@
public class AllValue extends ASTNodeAccessImpl implements Expression {
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
@Override
diff --git a/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java b/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java
index ce4885045..0c0d11146 100644
--- a/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java
@@ -9,24 +9,25 @@
*/
package net.sf.jsqlparser.expression;
-import java.util.List;
-import static java.util.stream.Collectors.joining;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
+import net.sf.jsqlparser.statement.select.Limit;
import net.sf.jsqlparser.statement.select.OrderByElement;
+import java.util.List;
+
+import static java.util.stream.Collectors.joining;
+
/**
* Analytic function. The name of the function is variable but the parameters following the special
- * analytic function path. e.g. row_number() over (order by test). Additional there can be an
- * expression for an analytical aggregate like sum(col) or the "all collumns" wildcard like
- * count(*).
+ * analytic function path. e.g. row_number() over (order by test). Additionally, there can be an
+ * expression for an analytical aggregate like sum(col) or the "all columns" wildcard like count(*).
*
* @author tw
*/
public class AnalyticExpression extends ASTNodeAccessImpl implements Expression {
- private final OrderByClause orderBy = new OrderByClause();
- private final PartitionByClause partitionBy = new PartitionByClause();
+
private String name;
private Expression expression;
private Expression offset;
@@ -36,51 +37,74 @@ public class AnalyticExpression extends ASTNodeAccessImpl implements Expression
private AnalyticType type = AnalyticType.OVER;
private boolean distinct = false;
private boolean unique = false;
- private boolean ignoreNulls = false; //IGNORE NULLS inside function parameters
- private boolean ignoreNullsOutside = false; //IGNORE NULLS outside function parameters
+ private boolean ignoreNullsOutside = false; // IGNORE NULLS outside function parameters
private Expression filterExpression = null;
- private WindowElement windowElement = null;
private List funcOrderBy = null;
+ private String onOverflowTruncate = null;
- public AnalyticExpression() {
- }
+ private String windowName = null; // refers to an external window definition (paritionBy,
+ // orderBy, windowElement)
+ private WindowDefinition windowDef = new WindowDefinition();
+
+ private Function.HavingClause havingClause;
+
+ private Function.NullHandling nullHandling = null;
+
+ private Limit limit = null;
+
+ public AnalyticExpression() {}
public AnalyticExpression(Function function) {
- name = function.getName();
- allColumns = function.isAllColumns();
- distinct = function.isDistinct();
- unique = function.isUnique();
- funcOrderBy = function.getOrderByElements();
+ this.name = String.join(" ", function.getMultipartName());
+ this.allColumns = function.isAllColumns();
+ this.distinct = function.isDistinct();
+ this.unique = function.isUnique();
- ExpressionList list = function.getParameters();
+ ExpressionList extends Expression> list = function.getParameters();
if (list != null) {
- if (list.getExpressions().size() > 3) {
- throw new IllegalArgumentException("function object not valid to initialize analytic expression");
+ if (list.size() > 3) {
+ throw new IllegalArgumentException(
+ "function object not valid to initialize analytic expression");
}
- expression = list.getExpressions().get(0);
- if (list.getExpressions().size() > 1) {
- offset = list.getExpressions().get(1);
+ expression = list.get(0);
+ if (list.size() > 1) {
+ offset = list.get(1);
}
- if (list.getExpressions().size() > 2) {
- defaultValue = list.getExpressions().get(2);
+ if (list.size() > 2) {
+ defaultValue = list.get(2);
}
}
- ignoreNulls = function.isIgnoreNulls();
- keep = function.getKeep();
+ this.havingClause = function.getHavingClause();
+ this.ignoreNullsOutside = function.isIgnoreNullsOutside();
+ this.nullHandling = function.getNullHandling();
+ this.funcOrderBy = function.getOrderByElements();
+ this.onOverflowTruncate = function.getOnOverflowTruncate();
+ this.limit = function.getLimit();
+ this.keep = function.getKeep();
}
+
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
public List getOrderByElements() {
- return orderBy.getOrderByElements();
+ return windowDef.orderBy.getOrderByElements();
}
public void setOrderByElements(List orderByElements) {
- orderBy.setOrderByElements(orderByElements);
+ windowDef.orderBy.setOrderByElements(orderByElements);
+ }
+
+ public String getOnOverflowTruncate() {
+ return onOverflowTruncate;
+ }
+
+ public AnalyticExpression setOnOverflowTruncate(String onOverflowTruncate) {
+ this.onOverflowTruncate = onOverflowTruncate;
+ return this;
}
public KeepExpression getKeep() {
@@ -91,20 +115,21 @@ public void setKeep(KeepExpression keep) {
this.keep = keep;
}
- public ExpressionList getPartitionExpressionList() {
- return partitionBy.getPartitionExpressionList();
+ public ExpressionList> getPartitionExpressionList() {
+ return windowDef.partitionBy;
}
- public void setPartitionExpressionList(ExpressionList partitionExpressionList) {
+ public void setPartitionExpressionList(ExpressionList partitionExpressionList) {
setPartitionExpressionList(partitionExpressionList, false);
}
- public void setPartitionExpressionList(ExpressionList partitionExpressionList, boolean brackets) {
- partitionBy.setPartitionExpressionList(partitionExpressionList, brackets);
+ public void setPartitionExpressionList(ExpressionList partitionExpressionList,
+ boolean brackets) {
+ windowDef.partitionBy.setExpressions(partitionExpressionList, brackets);
}
public boolean isPartitionByBrackets() {
- return partitionBy.isBrackets();
+ return windowDef.partitionBy.isBrackets();
}
public String getName() {
@@ -140,11 +165,11 @@ public void setDefaultValue(Expression defaultValue) {
}
public WindowElement getWindowElement() {
- return windowElement;
+ return windowDef.windowElement;
}
public void setWindowElement(WindowElement windowElement) {
- this.windowElement = windowElement;
+ windowDef.windowElement = windowElement;
}
public AnalyticType getType() {
@@ -172,11 +197,11 @@ public void setUnique(boolean unique) {
}
public boolean isIgnoreNulls() {
- return ignoreNulls;
+ return this.nullHandling == Function.NullHandling.IGNORE_NULLS;
}
public void setIgnoreNulls(boolean ignoreNulls) {
- this.ignoreNulls = ignoreNulls;
+ this.nullHandling = ignoreNulls ? Function.NullHandling.IGNORE_NULLS : null;
}
public boolean isIgnoreNullsOutside() {
@@ -187,8 +212,60 @@ public void setIgnoreNullsOutside(boolean ignoreNullsOutside) {
this.ignoreNullsOutside = ignoreNullsOutside;
}
+ public String getWindowName() {
+ return windowName;
+ }
+
+ public void setWindowName(String windowName) {
+ this.windowName = windowName;
+ }
+
+ public WindowDefinition getWindowDefinition() {
+ return windowDef;
+ }
+
+ public void setWindowDefinition(WindowDefinition windowDef) {
+ this.windowDef = windowDef;
+ }
+
+
+ public Function.HavingClause getHavingClause() {
+ return havingClause;
+ }
+
+ public AnalyticExpression setHavingClause(Function.HavingClause havingClause) {
+ this.havingClause = havingClause;
+ return this;
+ }
+
+ public AnalyticExpression setHavingClause(String havingType, Expression expression) {
+ this.havingClause = new Function.HavingClause(
+ Function.HavingClause.HavingType.valueOf(havingType.trim().toUpperCase()),
+ expression);
+ return this;
+ }
+
+ public Function.NullHandling getNullHandling() {
+ return nullHandling;
+ }
+
+ public AnalyticExpression setNullHandling(Function.NullHandling nullHandling) {
+ this.nullHandling = nullHandling;
+ return this;
+ }
+
+ public Limit getLimit() {
+ return limit;
+ }
+
+ public AnalyticExpression setLimit(Limit limit) {
+ this.limit = limit;
+ return this;
+ }
+
@Override
- @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity", "PMD.MissingBreakInSwitch"})
+ @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity",
+ "PMD.MissingBreakInSwitch"})
public String toString() {
StringBuilder b = new StringBuilder();
@@ -197,65 +274,94 @@ public String toString() {
b.append("DISTINCT ");
}
if (expression != null) {
- b.append(expression.toString());
+ b.append(expression);
if (offset != null) {
- b.append(", ").append(offset.toString());
+ b.append(", ").append(offset);
if (defaultValue != null) {
- b.append(", ").append(defaultValue.toString());
+ b.append(", ").append(defaultValue);
}
}
} else if (isAllColumns()) {
b.append("*");
}
- if (isIgnoreNulls()) {
- b.append(" IGNORE NULLS");
+
+ if (havingClause != null) {
+ havingClause.appendTo(b);
+ }
+
+ if (nullHandling != null && !ignoreNullsOutside) {
+ switch (nullHandling) {
+ case IGNORE_NULLS:
+ b.append(" IGNORE NULLS");
+ break;
+ case RESPECT_NULLS:
+ b.append(" RESPECT NULLS");
+ break;
+ }
}
- if (funcOrderBy!=null) {
+
+ if (funcOrderBy != null) {
b.append(" ORDER BY ");
- b.append( funcOrderBy.stream().map(OrderByElement::toString).collect(joining(", ")));
+ b.append(funcOrderBy.stream().map(OrderByElement::toString).collect(joining(", ")));
+ }
+
+ if (onOverflowTruncate != null) {
+ b.append(" ON OVERFLOW ").append(onOverflowTruncate);
+ }
+
+ if (limit != null) {
+ b.append(limit);
}
-
+
b.append(") ");
if (keep != null) {
- b.append(keep.toString()).append(" ");
+ b.append(keep).append(" ");
}
if (filterExpression != null) {
b.append("FILTER (WHERE ");
- b.append(filterExpression.toString());
+ b.append(filterExpression);
b.append(")");
if (type != AnalyticType.FILTER_ONLY) {
b.append(" ");
}
}
- if (isIgnoreNullsOutside()) {
- b.append("IGNORE NULLS ");
+ if (nullHandling != null && ignoreNullsOutside) {
+ switch (nullHandling) {
+ case IGNORE_NULLS:
+ b.append(" IGNORE NULLS ");
+ break;
+ case RESPECT_NULLS:
+ b.append(" RESPECT NULLS ");
+ break;
+ }
}
-
+
switch (type) {
case FILTER_ONLY:
return b.toString();
case WITHIN_GROUP:
b.append("WITHIN GROUP");
break;
+ case WITHIN_GROUP_OVER:
+ b.append("WITHIN GROUP (");
+ windowDef.orderBy.toStringOrderByElements(b);
+ b.append(") OVER (");
+ windowDef.partitionBy.toStringPartitionBy(b);
+ b.append(")");
+ break;
default:
b.append("OVER");
}
- b.append(" (");
- partitionBy.toStringPartitionBy(b);
- orderBy.toStringOrderByElements(b);
-
- if (windowElement != null) {
- if (orderBy.getOrderByElements() != null) {
- b.append(' ');
- }
- b.append(windowElement);
+ if (windowName != null) {
+ b.append(" ").append(windowName);
+ } else if (type != AnalyticType.WITHIN_GROUP_OVER) {
+ b.append(" ");
+ b.append(windowDef.toString());
}
- b.append(")");
-
return b.toString();
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/AnalyticType.java b/src/main/java/net/sf/jsqlparser/expression/AnalyticType.java
index 2f60840ff..2738849c6 100644
--- a/src/main/java/net/sf/jsqlparser/expression/AnalyticType.java
+++ b/src/main/java/net/sf/jsqlparser/expression/AnalyticType.java
@@ -10,7 +10,9 @@
package net.sf.jsqlparser.expression;
public enum AnalyticType {
- OVER,
- WITHIN_GROUP,
- FILTER_ONLY
+ OVER, WITHIN_GROUP, WITHIN_GROUP_OVER, FILTER_ONLY;
+
+ public static AnalyticType from(String type) {
+ return Enum.valueOf(AnalyticType.class, type.toUpperCase());
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/AnyComparisonExpression.java b/src/main/java/net/sf/jsqlparser/expression/AnyComparisonExpression.java
index 01a770950..cf3ba46d5 100644
--- a/src/main/java/net/sf/jsqlparser/expression/AnyComparisonExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/AnyComparisonExpression.java
@@ -9,9 +9,8 @@
*/
package net.sf.jsqlparser.expression;
-import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
-import net.sf.jsqlparser.statement.select.SubSelect;
+import net.sf.jsqlparser.statement.select.Select;
/**
* Combines ANY and SOME expressions.
@@ -19,56 +18,22 @@
* @author toben
*/
public class AnyComparisonExpression extends ASTNodeAccessImpl implements Expression {
-
- private final ItemsList itemsList;
- private boolean useBracketsForValues = false;
- private final SubSelect subSelect;
+ private final Select select;
private final AnyType anyType;
- public AnyComparisonExpression(AnyType anyType, SubSelect subSelect) {
- this.anyType = anyType;
- this.subSelect = subSelect;
- this.itemsList = null;
- }
-
- public AnyComparisonExpression(AnyType anyType, ItemsList itemsList) {
+ public AnyComparisonExpression(AnyType anyType, Select select) {
this.anyType = anyType;
- this.itemsList = itemsList;
- this.subSelect = null;
- }
-
- public SubSelect getSubSelect() {
- return subSelect;
- }
-
- public ItemsList getItemsList() {
- return itemsList;
- }
-
- public boolean isUsingItemsList() {
- return itemsList!=null;
+ this.select = select;
}
- public boolean isUsingSubSelect() {
- return subSelect!=null;
- }
-
- public boolean isUsingBracketsForValues() {
- return useBracketsForValues;
+ public Select getSelect() {
+ return select;
}
- public void setUseBracketsForValues(boolean useBracketsForValues) {
- this.useBracketsForValues = useBracketsForValues;
- }
-
- public AnyComparisonExpression withUseBracketsForValues(boolean useBracketsForValues) {
- this.setUseBracketsForValues(useBracketsForValues);
- return this;
- }
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
public AnyType getAnyType() {
@@ -77,12 +42,7 @@ public AnyType getAnyType() {
@Override
public String toString() {
- String s = anyType.name()
- + " ("
- + ( subSelect!=null
- ? subSelect.toString()
- : "VALUES " + itemsList.toString())
- + " )";
+ String s = anyType.name() + select;
return s;
}
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/AnyType.java b/src/main/java/net/sf/jsqlparser/expression/AnyType.java
index 460de9704..fec6fb09d 100644
--- a/src/main/java/net/sf/jsqlparser/expression/AnyType.java
+++ b/src/main/java/net/sf/jsqlparser/expression/AnyType.java
@@ -10,8 +10,9 @@
package net.sf.jsqlparser.expression;
public enum AnyType {
+ ANY, SOME, ALL;
- ANY,
- SOME,
- ALL
+ public static AnyType from(String type) {
+ return Enum.valueOf(AnyType.class, type.toUpperCase());
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/ArrayConstructor.java b/src/main/java/net/sf/jsqlparser/expression/ArrayConstructor.java
index 079191622..5e1c8d0e6 100644
--- a/src/main/java/net/sf/jsqlparser/expression/ArrayConstructor.java
+++ b/src/main/java/net/sf/jsqlparser/expression/ArrayConstructor.java
@@ -9,20 +9,29 @@
*/
package net.sf.jsqlparser.expression;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
-import net.sf.jsqlparser.statement.select.PlainSelect;
-
-import java.util.List;
+import net.sf.jsqlparser.statement.create.table.ColDataType;
public class ArrayConstructor extends ASTNodeAccessImpl implements Expression {
- private List expressions;
+ private ExpressionList> expressions;
private boolean arrayKeyword;
+ private ColDataType dataType;
+
+ public ArrayConstructor(ExpressionList> expressions, boolean arrayKeyword) {
+ this.expressions = expressions;
+ this.arrayKeyword = arrayKeyword;
+ }
+
+ public ArrayConstructor(Expression... expressions) {
+ this(new ExpressionList(expressions), false);
+ }
- public List getExpressions() {
+ public ExpressionList> getExpressions() {
return expressions;
}
- public void setExpressions(List expressions) {
+ public void setExpressions(ExpressionList> expressions) {
this.expressions = expressions;
}
@@ -34,14 +43,18 @@ public void setArrayKeyword(boolean arrayKeyword) {
this.arrayKeyword = arrayKeyword;
}
- public ArrayConstructor(List expressions, boolean arrayKeyword) {
- this.expressions = expressions;
- this.arrayKeyword = arrayKeyword;
+ public ColDataType getDataType() {
+ return dataType;
+ }
+
+ public ArrayConstructor setDataType(ColDataType dataType) {
+ this.dataType = dataType;
+ return this;
}
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
@Override
@@ -49,9 +62,13 @@ public String toString() {
StringBuilder sb = new StringBuilder();
if (arrayKeyword) {
sb.append("ARRAY");
+
+ if (dataType != null) {
+ sb.append("<").append(dataType).append(">");
+ }
}
sb.append("[");
- sb.append(PlainSelect.getStringList(expressions, true, false));
+ sb.append(expressions.toString());
sb.append("]");
return sb.toString();
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/ArrayExpression.java b/src/main/java/net/sf/jsqlparser/expression/ArrayExpression.java
index aef63b8f6..e86f34cad 100644
--- a/src/main/java/net/sf/jsqlparser/expression/ArrayExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/ArrayExpression.java
@@ -23,13 +23,23 @@ public ArrayExpression() {
// empty constructor
}
- public ArrayExpression(Expression objExpression, Expression indexExpression, Expression startIndexExpression, Expression stopIndexExpression) {
+ public ArrayExpression(Expression objExpression, Expression indexExpression,
+ Expression startIndexExpression, Expression stopIndexExpression) {
this.objExpression = objExpression;
this.indexExpression = indexExpression;
this.startIndexExpression = startIndexExpression;
this.stopIndexExpression = stopIndexExpression;
}
+ public ArrayExpression(Expression objExpression, Expression indexExpression) {
+ this(objExpression, indexExpression, null, null);
+ }
+
+ public ArrayExpression(Expression objExpression, Expression startIndexExpression,
+ Expression stopIndexExpression) {
+ this(objExpression, null, startIndexExpression, stopIndexExpression);
+ }
+
public Expression getObjExpression() {
return objExpression;
}
@@ -63,8 +73,8 @@ public void setStopIndexExpression(Expression stopIndexExpression) {
}
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
@Override
@@ -90,7 +100,8 @@ public ArrayExpression withIndexExpression(Expression indexExpression) {
return this;
}
- public ArrayExpression withRangeExpression(Expression startIndexExpression, Expression stopIndexExpression) {
+ public ArrayExpression withRangeExpression(Expression startIndexExpression,
+ Expression stopIndexExpression) {
this.setStartIndexExpression(startIndexExpression);
this.setStopIndexExpression(stopIndexExpression);
return this;
diff --git a/src/main/java/net/sf/jsqlparser/expression/BinaryExpression.java b/src/main/java/net/sf/jsqlparser/expression/BinaryExpression.java
index cf87acfb3..ffd9c2d84 100644
--- a/src/main/java/net/sf/jsqlparser/expression/BinaryExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/BinaryExpression.java
@@ -9,8 +9,27 @@
*/
package net.sf.jsqlparser.expression;
+import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
+import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
+import net.sf.jsqlparser.expression.operators.arithmetic.Division;
+import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
+import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
+import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
+import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
+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.parser.ASTNodeAccessImpl;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.Iterator;
+
/**
* A basic class for binary expressions, that is expressions having a left member and a right member
* which are in turn expressions.
@@ -19,52 +38,220 @@ public abstract class BinaryExpression extends ASTNodeAccessImpl implements Expr
private Expression leftExpression;
private Expression rightExpression;
- // private boolean not = false;
- public BinaryExpression() {
+ public BinaryExpression() {}
+
+ public BinaryExpression(Expression leftExpression, Expression rightExpression) {
+ this.leftExpression = leftExpression;
+ this.rightExpression = rightExpression;
+ }
+
+ public static Expression build(Class extends BinaryExpression> clz, Expression... expressions)
+ throws NoSuchMethodException, InvocationTargetException, InstantiationException,
+ IllegalAccessException {
+ switch (expressions.length) {
+ case 0:
+ return new NullValue();
+ case 1:
+ return expressions[0];
+ default:
+ Iterator it = Arrays.stream(expressions).iterator();
+
+ Expression leftExpression = it.next();
+ Expression rightExpression = it.next();
+ BinaryExpression binaryExpression =
+ clz.getConstructor(Expression.class, Expression.class)
+ .newInstance(leftExpression, rightExpression);
+
+ while (it.hasNext()) {
+ rightExpression = it.next();
+ binaryExpression = clz.getConstructor(Expression.class, Expression.class)
+ .newInstance(binaryExpression, rightExpression);
+ }
+ return binaryExpression;
+ }
+ }
+
+ public static Expression add(Expression... expressions) {
+ try {
+ return build(Addition.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression bitAnd(Expression... expressions) {
+ try {
+ return build(BitwiseAnd.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression bitShiftLeft(Expression... expressions) {
+ try {
+ return build(BitwiseLeftShift.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression multiply(Expression... expressions) {
+ try {
+ return build(Multiplication.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression bitOr(Expression... expressions) {
+ try {
+ return build(BitwiseOr.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression bitShiftRight(Expression... expressions) {
+ try {
+ return build(BitwiseRightShift.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression bitXor(Expression... expressions) {
+ try {
+ return build(BitwiseXor.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression concat(Expression... expressions) {
+ try {
+ return build(Concat.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression divide(Expression... expressions) {
+ try {
+ return build(Division.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression divideInt(Expression... expressions) {
+ try {
+ return build(IntegerDivision.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression modulo(Expression... expressions) {
+ try {
+ return build(Modulo.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression subtract(Expression... expressions) {
+ try {
+ return build(Subtraction.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression or(Expression... expressions) {
+ try {
+ return build(OrExpression.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression xor(Expression... expressions) {
+ try {
+ return build(XorExpression.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Expression and(Expression... expressions) {
+ try {
+ return build(AndExpression.class, expressions);
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException
+ | IllegalAccessException e) {
+ // this should never happen, at least I don't see how
+ throw new RuntimeException(e);
+ }
}
public Expression getLeftExpression() {
return leftExpression;
}
+ public void setLeftExpression(Expression expression) {
+ leftExpression = expression;
+ }
+
public Expression getRightExpression() {
return rightExpression;
}
+ public void setRightExpression(Expression expression) {
+ rightExpression = expression;
+ }
+
public BinaryExpression withLeftExpression(Expression expression) {
setLeftExpression(expression);
return this;
}
- public void setLeftExpression(Expression expression) {
- leftExpression = expression;
- }
-
public BinaryExpression withRightExpression(Expression expression) {
setRightExpression(expression);
return this;
}
- public void setRightExpression(Expression expression) {
- rightExpression = expression;
- }
-
- // public void setNot() {
- // not = true;
- // }
- //
- // public void removeNot() {
- // not = false;
- // }
- //
- // public boolean isNot() {
- // return not;
- // }
@Override
public String toString() {
return // (not ? "NOT " : "") +
- getLeftExpression() + " " + getStringExpression() + " " + getRightExpression();
+ getLeftExpression() + " " + getStringExpression() + " " + getRightExpression();
}
public abstract String getStringExpression();
diff --git a/src/main/java/net/sf/jsqlparser/expression/BooleanValue.java b/src/main/java/net/sf/jsqlparser/expression/BooleanValue.java
new file mode 100644
index 000000000..258a89e16
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/expression/BooleanValue.java
@@ -0,0 +1,74 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2024 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.expression;
+
+import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
+
+import java.util.Objects;
+
+/**
+ * A boolean value true/false
+ */
+public final class BooleanValue extends ASTNodeAccessImpl implements Expression {
+
+ private boolean value = false;
+
+ public BooleanValue() {
+ // empty constructor
+ }
+
+ public BooleanValue(String value) {
+ this(Boolean.parseBoolean(value));
+ }
+
+ public BooleanValue(boolean bool) {
+ value = bool;
+ }
+
+ public boolean getValue() {
+ return value;
+ }
+
+ public void setValue(boolean bool) {
+ value = bool;
+ }
+
+ @Override
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
+ }
+
+ @Override
+ public String toString() {
+ return Boolean.toString(value);
+ }
+
+ public BooleanValue withValue(boolean bool) {
+ this.setValue(bool);
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ BooleanValue that = (BooleanValue) o;
+ return Objects.equals(value, that.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(value);
+ }
+}
diff --git a/src/main/java/net/sf/jsqlparser/expression/CaseExpression.java b/src/main/java/net/sf/jsqlparser/expression/CaseExpression.java
index 371c40bf0..10fd7d56d 100644
--- a/src/main/java/net/sf/jsqlparser/expression/CaseExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/CaseExpression.java
@@ -10,36 +10,43 @@
package net.sf.jsqlparser.expression;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
import net.sf.jsqlparser.statement.select.PlainSelect;
/**
* CASE/WHEN expression.
+ *
+ * Syntax:
*
- * Syntax:
+ *
+ *
* CASE
* WHEN condition THEN expression
* [WHEN condition THEN expression]...
* [ELSE expression]
* END
- *
+ *
+ *
*
*
* or
*
*
- *
+ *
+ *
* CASE expression
* WHEN condition THEN expression
* [WHEN condition THEN expression]...
* [ELSE expression]
* END
- *
- *
+ *
+ *
*/
public class CaseExpression extends ASTNodeAccessImpl implements Expression {
@@ -48,9 +55,21 @@ public class CaseExpression extends ASTNodeAccessImpl implements Expression {
private List whenClauses;
private Expression elseExpression;
+ public CaseExpression() {}
+
+ public CaseExpression(WhenClause... whenClauses) {
+ this.whenClauses = Arrays.asList(whenClauses);
+ }
+
+ public CaseExpression(Expression elseExpression, WhenClause... whenClauses) {
+ this.elseExpression = elseExpression;
+ this.whenClauses = Arrays.asList(whenClauses);
+ }
+
+
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
public Expression getSwitchExpression() {
@@ -91,9 +110,11 @@ public void setWhenClauses(List whenClauses) {
@Override
public String toString() {
- return (usingBrackets ? "(" : "") + "CASE " + ((switchExpression != null) ? switchExpression + " " : "")
+ return (usingBrackets ? "(" : "") + "CASE "
+ + ((switchExpression != null) ? switchExpression + " " : "")
+ PlainSelect.getStringList(whenClauses, false, false) + " "
- + ((elseExpression != null) ? "ELSE " + elseExpression + " " : "") + "END" + (usingBrackets ? ")" : "");
+ + ((elseExpression != null) ? "ELSE " + elseExpression + " " : "") + "END"
+ + (usingBrackets ? ")" : "");
}
public CaseExpression withSwitchExpression(Expression switchExpression) {
@@ -101,6 +122,10 @@ public CaseExpression withSwitchExpression(Expression switchExpression) {
return this;
}
+ public CaseExpression withWhenClauses(WhenClause... whenClauses) {
+ return this.withWhenClauses(Arrays.asList(whenClauses));
+ }
+
public CaseExpression withWhenClauses(List whenClauses) {
this.setWhenClauses(whenClauses);
return this;
@@ -112,13 +137,15 @@ public CaseExpression withElseExpression(Expression elseExpression) {
}
public CaseExpression addWhenClauses(WhenClause... whenClauses) {
- List collection = Optional.ofNullable(getWhenClauses()).orElseGet(ArrayList::new);
+ List collection =
+ Optional.ofNullable(getWhenClauses()).orElseGet(ArrayList::new);
Collections.addAll(collection, whenClauses);
return this.withWhenClauses(collection);
}
public CaseExpression addWhenClauses(Collection extends WhenClause> whenClauses) {
- List collection = Optional.ofNullable(getWhenClauses()).orElseGet(ArrayList::new);
+ List collection =
+ Optional.ofNullable(getWhenClauses()).orElseGet(ArrayList::new);
collection.addAll(whenClauses);
return this.withWhenClauses(collection);
}
@@ -131,25 +158,25 @@ public E getElseExpression(Class type) {
return type.cast(getElseExpression());
}
- /**
- * @return the usingBrackets
- */
- public boolean isUsingBrackets() {
- return usingBrackets;
- }
-
- /**
- * @param usingBrackets the usingBrackets to set
- */
- public void setUsingBrackets(boolean usingBrackets) {
- this.usingBrackets = usingBrackets;
- }
-
- /**
- * @param usingBrackets the usingBrackets to set
- */
- public CaseExpression withUsingBrackets(boolean usingBrackets) {
- this.usingBrackets=usingBrackets;
- return this;
+ /**
+ * @return the usingBrackets
+ */
+ public boolean isUsingBrackets() {
+ return usingBrackets;
+ }
+
+ /**
+ * @param usingBrackets the usingBrackets to set
+ */
+ public void setUsingBrackets(boolean usingBrackets) {
+ this.usingBrackets = usingBrackets;
+ }
+
+ /**
+ * @param usingBrackets the usingBrackets to set
+ */
+ public CaseExpression withUsingBrackets(boolean usingBrackets) {
+ this.usingBrackets = usingBrackets;
+ return this;
}
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/CastExpression.java b/src/main/java/net/sf/jsqlparser/expression/CastExpression.java
index 519eb4ef6..f06682068 100644
--- a/src/main/java/net/sf/jsqlparser/expression/CastExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/CastExpression.java
@@ -11,35 +11,141 @@
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
import net.sf.jsqlparser.statement.create.table.ColDataType;
+import net.sf.jsqlparser.statement.create.table.ColumnDefinition;
+import net.sf.jsqlparser.statement.select.Select;
+
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class CastExpression extends ASTNodeAccessImpl implements Expression {
+ private final static Pattern PATTERN =
+ Pattern.compile("(^[a-z0-9_]*){1}", Pattern.CASE_INSENSITIVE);
+ public String keyword;
private Expression leftExpression;
- private ColDataType type;
- private RowConstructor rowConstructor;
- private boolean useCastKeyword = true;
-
- public RowConstructor getRowConstructor() {
- return rowConstructor;
- }
-
- public void setRowConstructor(RowConstructor rowConstructor) {
- this.rowConstructor = rowConstructor;
- this.type = null;
- }
-
- public CastExpression withRowConstructor(RowConstructor rowConstructor) {
- setRowConstructor(rowConstructor);
- return this;
+ private ColDataType colDataType = null;
+ private ArrayList columnDefinitions = new ArrayList<>();
+
+ private boolean isImplicitCast = false;
+
+ // BigQuery specific FORMAT clause:
+ // https://cloud.google.com/bigquery/docs/reference/standard-sql/conversion_functions#cast_as_date
+ private String format = null;
+
+ public CastExpression(String keyword, Expression leftExpression, String dataType) {
+ this.keyword = keyword;
+ this.leftExpression = leftExpression;
+ this.colDataType = new ColDataType(dataType);
+ }
+
+ // Implicit Cast
+ public CastExpression(String dataType, String value) {
+ this.keyword = null;
+ this.isImplicitCast = true;
+ this.colDataType = new ColDataType(dataType);
+ this.leftExpression = new StringValue(value);
+ }
+
+ public CastExpression(ColDataType colDataType, String value) {
+ this.keyword = null;
+ this.isImplicitCast = true;
+ this.colDataType = colDataType;
+ this.leftExpression = new StringValue(value);
+ }
+
+ public CastExpression(ColDataType colDataType, Long value) {
+ this.keyword = null;
+ this.isImplicitCast = true;
+ this.colDataType = colDataType;
+ this.leftExpression = new LongValue(value);
+ }
+
+ public CastExpression(ColDataType colDataType, Double value) {
+ this.keyword = null;
+ this.isImplicitCast = true;
+ this.colDataType = colDataType;
+ this.leftExpression = new DoubleValue(value);
+ }
+
+ public CastExpression(Expression leftExpression, String dataType) {
+ this.keyword = null;
+ this.leftExpression = leftExpression;
+ this.colDataType = new ColDataType(dataType);
+ }
+
+
+ public CastExpression(String keyword) {
+ this.keyword = keyword;
+ }
+
+ public CastExpression() {
+ this("CAST");
+ }
+
+ public static boolean isOf(ColDataType colDataType, DataType... types) {
+ return Set.of(types).contains(DataType.from(colDataType.getDataType()));
+ }
+
+ public static boolean isTime(ColDataType colDataType) {
+ return isOf(colDataType, DataType.TIME, DataType.TIME_WITH_TIME_ZONE,
+ DataType.TIME_WITHOUT_TIME_ZONE);
+ }
+
+ public static boolean isTimeStamp(ColDataType colDataType) {
+ return isOf(colDataType, DataType.TIMESTAMP_NS, DataType.TIMESTAMP,
+ DataType.TIMESTAMP_WITHOUT_TIME_ZONE,
+ DataType.DATETIME, DataType.TIMESTAMP_MS, DataType.TIMESTAMP_S,
+ DataType.TIMESTAMPTZ, DataType.TIMESTAMP_WITH_TIME_ZONE);
+ }
+
+ public static boolean isDate(ColDataType colDataType) {
+ return isOf(colDataType, DataType.DATE);
+ }
+
+ public static boolean isBLOB(ColDataType colDataType) {
+ return isOf(colDataType, DataType.BLOB, DataType.BYTEA, DataType.BINARY, DataType.VARBINARY,
+ DataType.BYTES, DataType.VARBYTE);
+ }
+
+ public static boolean isFloat(ColDataType colDataType) {
+ return isOf(colDataType, DataType.REAL, DataType.FLOAT4, DataType.FLOAT, DataType.DOUBLE,
+ DataType.DOUBLE_PRECISION, DataType.FLOAT8);
+ }
+
+ public static boolean isInteger(ColDataType colDataType) {
+ return isOf(colDataType, DataType.TINYINT, DataType.INT1, DataType.SMALLINT, DataType.INT2,
+ DataType.SHORT, DataType.INTEGER, DataType.INT4, DataType.INT, DataType.SIGNED,
+ DataType.BIGINT, DataType.INT8, DataType.LONG, DataType.HUGEINT, DataType.UTINYINT,
+ DataType.USMALLINT, DataType.UINTEGER, DataType.UBIGINT, DataType.UHUGEINT);
+ }
+
+ public static boolean isDecimal(ColDataType colDataType) {
+ return isOf(colDataType, DataType.DECIMAL, DataType.NUMBER, DataType.NUMERIC);
+ }
+
+ public static boolean isText(ColDataType colDataType) {
+ return isOf(colDataType, DataType.VARCHAR, DataType.NVARCHAR, DataType.CHAR, DataType.NCHAR,
+ DataType.BPCHAR, DataType.STRING, DataType.TEXT, DataType.CLOB);
+ }
+
+ public ColDataType getColDataType() {
+ return colDataType;
}
- public ColDataType getType() {
- return type;
+ public void setColDataType(ColDataType colDataType) {
+ this.colDataType = colDataType;
}
- public void setType(ColDataType type) {
- this.type = type;
- this.rowConstructor = null;
+ public ArrayList getColumnDefinitions() {
+ return columnDefinitions;
+ }
+
+ public void addColumnDefinition(ColumnDefinition columnDefinition) {
+ this.columnDefinitions.add(columnDefinition);
}
public Expression getLeftExpression() {
@@ -50,32 +156,65 @@ public void setLeftExpression(Expression expression) {
leftExpression = expression;
}
+ public boolean isImplicitCast() {
+ return isImplicitCast;
+ }
+
+ public CastExpression setImplicitCast(boolean implicitCast) {
+ isImplicitCast = implicitCast;
+ return this;
+ }
+
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
+ @Deprecated
public boolean isUseCastKeyword() {
- return useCastKeyword;
+ return keyword != null && !keyword.isEmpty();
}
+ @Deprecated
public void setUseCastKeyword(boolean useCastKeyword) {
- this.useCastKeyword = useCastKeyword;
+ if (useCastKeyword) {
+ if (keyword == null || keyword.isEmpty()) {
+ keyword = "CAST";
+ }
+ } else {
+ keyword = null;
+ }
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ public CastExpression setFormat(String format) {
+ this.format = format;
+ return this;
}
@Override
public String toString() {
- if (useCastKeyword) {
- return rowConstructor!=null
- ? "CAST(" + leftExpression + " AS " + rowConstructor.toString() + ")"
- : "CAST(" + leftExpression + " AS " + type.toString() + ")";
+ String formatStr = format != null && !format.isEmpty()
+ ? " FORMAT " + format
+ : "";
+ if (isImplicitCast) {
+ return colDataType + " " + leftExpression;
+ } else if (keyword != null && !keyword.isEmpty()) {
+ return columnDefinitions.size() > 1
+ ? keyword + "(" + leftExpression + " AS ROW("
+ + Select.getStringList(columnDefinitions) + ")" + formatStr + ")"
+ : keyword + "(" + leftExpression + " AS " + colDataType.toString() + formatStr
+ + ")";
} else {
- return leftExpression + "::" + type.toString();
+ return leftExpression + "::" + colDataType.toString();
}
}
public CastExpression withType(ColDataType type) {
- this.setType(type);
+ this.setColDataType(type);
return this;
}
@@ -92,4 +231,65 @@ public CastExpression withLeftExpression(Expression leftExpression) {
public E getLeftExpression(Class type) {
return type.cast(getLeftExpression());
}
+
+ public boolean isOf(CastExpression anotherCast) {
+ return this.colDataType.equals(anotherCast.colDataType);
+ }
+
+ public boolean isOf(DataType... types) {
+ return Set.of(types).contains(DataType.from(colDataType.getDataType()));
+ }
+
+ public boolean isTime() {
+ return isTime(this.colDataType);
+ }
+
+ public boolean isTimeStamp() {
+ return isTimeStamp(this.colDataType);
+ }
+
+ public boolean isDate() {
+ return isDate(this.colDataType);
+ }
+
+ public boolean isBLOB() {
+ return isBLOB(this.colDataType);
+ }
+
+ public boolean isFloat() {
+ return isFloat(this.colDataType);
+ }
+
+ public boolean isInteger() {
+ return isInteger(this.colDataType);
+ }
+
+ public boolean isDecimal() {
+ return isDecimal(this.colDataType);
+ }
+
+ public boolean isText() {
+ return isText(this.colDataType);
+ }
+
+ public enum DataType {
+ ARRAY, BIT, BITSTRING, BLOB, BYTEA, BINARY, VARBINARY, BYTES, BOOLEAN, BOOL, ENUM, INTERVAL, LIST, MAP, STRUCT, TINYINT, INT1, SMALLINT, INT2, SHORT, INTEGER, INT4, INT, SIGNED, BIGINT, INT8, LONG, HUGEINT, UTINYINT, USMALLINT, UINTEGER, UBIGINT, UHUGEINT, DECIMAL, NUMBER, NUMERIC, REAL, FLOAT4, FLOAT, DOUBLE, DOUBLE_PRECISION, FLOAT8, FLOAT64, UUID, VARCHAR, NVARCHAR, CHAR, NCHAR, BPCHAR, STRING, TEXT, CLOB, DATE, TIME, TIME_WITHOUT_TIME_ZONE, TIMETZ, TIME_WITH_TIME_ZONE, TIMESTAMP_NS, TIMESTAMP, TIMESTAMP_WITHOUT_TIME_ZONE, DATETIME, TIMESTAMP_MS, TIMESTAMP_S, TIMESTAMPTZ, TIMESTAMP_WITH_TIME_ZONE, UNKNOWN, VARBYTE, JSON;
+
+ public static DataType from(String typeStr) {
+ Matcher matcher = PATTERN.matcher(typeStr.trim().replaceAll("\\s+", "_").toUpperCase());
+ if (matcher.find()) {
+ try {
+ return Enum.valueOf(DataType.class, matcher.group(0));
+ } catch (Exception ex) {
+ Logger.getLogger(CastExpression.class.getName()).log(Level.FINE,
+ "Type " + typeStr + " unknown", ex);
+ return DataType.UNKNOWN;
+ }
+ } else {
+ Logger.getLogger(CastExpression.class.getName()).log(Level.FINE,
+ "Type " + typeStr + " unknown");
+ return DataType.UNKNOWN;
+ }
+ }
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/CollateExpression.java b/src/main/java/net/sf/jsqlparser/expression/CollateExpression.java
index 07c2b8616..8a419b241 100644
--- a/src/main/java/net/sf/jsqlparser/expression/CollateExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/CollateExpression.java
@@ -26,8 +26,8 @@ public CollateExpression(Expression leftExpression, String collate) {
}
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
public Expression getLeftExpression() {
diff --git a/src/main/java/net/sf/jsqlparser/expression/ConnectByPriorOperator.java b/src/main/java/net/sf/jsqlparser/expression/ConnectByPriorOperator.java
new file mode 100644
index 000000000..45c2fde6a
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/expression/ConnectByPriorOperator.java
@@ -0,0 +1,74 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2021 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+/*
+ * Copyright (C) 2021 JSQLParser.
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation; either version
+ * 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this library;
+ * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+package net.sf.jsqlparser.expression;
+
+import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
+import net.sf.jsqlparser.schema.Column;
+
+import java.util.Objects;
+
+/**
+ *
+ * @author are
+ */
+public class ConnectByPriorOperator extends ASTNodeAccessImpl implements Expression {
+ private final Expression expression;
+
+ @Deprecated
+ public ConnectByPriorOperator(Column column) {
+ this.expression = Objects.requireNonNull(column,
+ "The COLUMN of the ConnectByPrior Operator must not be null");
+ }
+
+ public ConnectByPriorOperator(Expression column) {
+ this.expression = Objects.requireNonNull(column,
+ "The COLUMN of the ConnectByPrior Operator must not be null");
+ }
+
+ @Deprecated
+ public Expression getColumn() {
+ return getExpression();
+ }
+
+ public Expression getExpression() {
+ return expression;
+ }
+
+ @Override
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
+ }
+
+ public StringBuilder appendTo(StringBuilder builder) {
+ builder.append("PRIOR ").append(expression);
+ return builder;
+ }
+
+ @Override
+ public String toString() {
+ return appendTo(new StringBuilder()).toString();
+ }
+}
diff --git a/src/main/java/net/sf/jsqlparser/expression/ConnectByRootOperator.java b/src/main/java/net/sf/jsqlparser/expression/ConnectByRootOperator.java
index 817023422..776dc031e 100644
--- a/src/main/java/net/sf/jsqlparser/expression/ConnectByRootOperator.java
+++ b/src/main/java/net/sf/jsqlparser/expression/ConnectByRootOperator.java
@@ -26,34 +26,46 @@
package net.sf.jsqlparser.expression;
import java.util.Objects;
+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
import net.sf.jsqlparser.schema.Column;
/**
- *
* @author are
*/
public class ConnectByRootOperator extends ASTNodeAccessImpl implements Expression {
- private final Column column;
+ private final Expression expression;
+ @Deprecated
public ConnectByRootOperator(Column column) {
- this.column = Objects.requireNonNull(column, "The COLUMN of the ConnectByRoot Operator must not be null");
+ this.expression = Objects.requireNonNull(column,
+ "The COLUMN of the ConnectByRoot Operator must not be null");
+ }
+
+ public ConnectByRootOperator(Expression column) {
+ this.expression = Objects.requireNonNull(column,
+ "The EXPRESSION of the ConnectByRoot Operator must not be null");
}
- public Column getColumn() {
- return column;
+ @Deprecated
+ public Expression getColumn() {
+ return expression;
+ }
+
+ public Expression getExpression() {
+ return expression;
}
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
-
+
public StringBuilder appendTo(StringBuilder builder) {
- builder.append("CONNECT_BY_ROOT ").append(column);
+ builder.append("CONNECT_BY_ROOT ").append(expression);
return builder;
}
-
+
@Override
public String toString() {
return appendTo(new StringBuilder()).toString();
diff --git a/src/main/java/net/sf/jsqlparser/expression/DateTimeLiteralExpression.java b/src/main/java/net/sf/jsqlparser/expression/DateTimeLiteralExpression.java
index 173c564f7..ccb15db4b 100644
--- a/src/main/java/net/sf/jsqlparser/expression/DateTimeLiteralExpression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/DateTimeLiteralExpression.java
@@ -33,13 +33,13 @@ public void setType(DateTime type) {
}
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
@Override
public String toString() {
- return type.name() + " " + value;
+ return type != null ? type.name() + " " + value : value;
}
public DateTimeLiteralExpression withValue(String value) {
@@ -53,6 +53,10 @@ public DateTimeLiteralExpression withType(DateTime type) {
}
public enum DateTime {
- DATE, TIME, TIMESTAMP;
+ DATE, DATETIME, TIME, TIMESTAMP, TIMESTAMPTZ;
+
+ public static DateTime from(String dateTimeStr) {
+ return Enum.valueOf(DateTime.class, dateTimeStr.toUpperCase());
+ }
}
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/DateValue.java b/src/main/java/net/sf/jsqlparser/expression/DateValue.java
index 8c28a5fdd..d03a73c66 100644
--- a/src/main/java/net/sf/jsqlparser/expression/DateValue.java
+++ b/src/main/java/net/sf/jsqlparser/expression/DateValue.java
@@ -38,8 +38,8 @@ public DateValue(String value) {
}
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
public Date getValue() {
diff --git a/src/main/java/net/sf/jsqlparser/expression/DoubleValue.java b/src/main/java/net/sf/jsqlparser/expression/DoubleValue.java
index 43e072dcf..8d25aa61a 100644
--- a/src/main/java/net/sf/jsqlparser/expression/DoubleValue.java
+++ b/src/main/java/net/sf/jsqlparser/expression/DoubleValue.java
@@ -16,7 +16,7 @@
*/
public class DoubleValue extends ASTNodeAccessImpl implements Expression {
- private double value;
+ private Double value;
private String stringValue;
public DoubleValue() {
@@ -24,6 +24,9 @@ public DoubleValue() {
}
public DoubleValue(final String value) {
+ if (value == null || value.length() == 0) {
+ throw new IllegalArgumentException("value can neither be null nor empty.");
+ }
String val = value;
if (val.charAt(0) == '+') {
val = val.substring(1);
@@ -32,17 +35,23 @@ public DoubleValue(final String value) {
this.stringValue = val;
}
+ public DoubleValue(final double value) {
+ this.value = value;
+ this.stringValue = String.valueOf(value);
+ }
+
@Override
- public void accept(ExpressionVisitor expressionVisitor) {
- expressionVisitor.visit(this);
+ public T accept(ExpressionVisitor expressionVisitor, S context) {
+ return expressionVisitor.visit(this, context);
}
public double getValue() {
return value;
}
- public void setValue(double d) {
+ public void setValue(Double d) {
value = d;
+ stringValue = String.valueOf(value);
}
@Override
@@ -50,7 +59,7 @@ public String toString() {
return stringValue;
}
- public DoubleValue withValue(double value) {
+ public DoubleValue withValue(Double value) {
this.setValue(value);
return this;
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/Expression.java b/src/main/java/net/sf/jsqlparser/expression/Expression.java
index daeb2da83..1f733d564 100644
--- a/src/main/java/net/sf/jsqlparser/expression/Expression.java
+++ b/src/main/java/net/sf/jsqlparser/expression/Expression.java
@@ -14,6 +14,10 @@
public interface Expression extends ASTNodeAccess, Model {
- void accept(ExpressionVisitor expressionVisitor);
+ T accept(ExpressionVisitor expressionVisitor, S context);
+
+ default void accept(ExpressionVisitor expressionVisitor) {
+ this.accept(expressionVisitor, null);
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java
index ed4460e1c..8b5ade13d 100644
--- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java
+++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java
@@ -9,185 +9,774 @@
*/
package net.sf.jsqlparser.expression;
-import net.sf.jsqlparser.expression.operators.arithmetic.*;
+import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
+import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
+import net.sf.jsqlparser.expression.operators.arithmetic.Division;
+import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
+import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
+import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
+import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
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.*;
+import net.sf.jsqlparser.expression.operators.relational.Between;
+import net.sf.jsqlparser.expression.operators.relational.ContainedBy;
+import net.sf.jsqlparser.expression.operators.relational.Contains;
+import net.sf.jsqlparser.expression.operators.relational.CosineSimilarity;
+import net.sf.jsqlparser.expression.operators.relational.DoubleAnd;
+import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
+import net.sf.jsqlparser.expression.operators.relational.ExcludesExpression;
+import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.FullTextSearch;
+import net.sf.jsqlparser.expression.operators.relational.GeometryDistance;
+import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
+import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
+import net.sf.jsqlparser.expression.operators.relational.InExpression;
+import net.sf.jsqlparser.expression.operators.relational.IncludesExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsBooleanExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsDistinctExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsUnknownExpression;
+import net.sf.jsqlparser.expression.operators.relational.JsonOperator;
+import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
+import net.sf.jsqlparser.expression.operators.relational.Matches;
+import net.sf.jsqlparser.expression.operators.relational.MemberOfExpression;
+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.expression.operators.relational.Plus;
+import net.sf.jsqlparser.expression.operators.relational.PriorTo;
+import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
+import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
+import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin;
+import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin;
import net.sf.jsqlparser.schema.Column;
+import net.sf.jsqlparser.statement.piped.FromQuery;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
-import net.sf.jsqlparser.statement.select.SubSelect;
+import net.sf.jsqlparser.statement.select.FunctionAllColumns;
+import net.sf.jsqlparser.statement.select.GroupByElement;
+import net.sf.jsqlparser.statement.select.Limit;
+import net.sf.jsqlparser.statement.select.OrderByElement;
+import net.sf.jsqlparser.statement.select.ParenthesedSelect;
+import net.sf.jsqlparser.statement.select.Select;
+import net.sf.jsqlparser.statement.update.UpdateSet;
+
+import java.util.List;
+
+public interface ExpressionVisitor {
+
+ default T visitExpressions(ExpressionList extends Expression> expressions, S context) {
+ if (expressions != null) {
+ expressions.forEach(expression -> expression.accept(this, context));
+ }
+ return null;
+ };
+
+ default T visitExpression(Expression expression, S context) {
+ if (expression != null) {
+ expression.accept(this, context);
+ }
+ return null;
+ }
+
+ default T visitOrderBy(List orderByElements, S context) {
+ if (orderByElements != null) {
+ for (OrderByElement orderByElement : orderByElements) {
+ orderByElement.getExpression().accept(this, context);
+ }
+ }
+ return null;
+ }
+
+ default T visitLimit(Limit limit, S context) {
+ if (limit != null && !limit.isLimitNull() && !limit.isLimitAll()) {
+ if (limit.getOffset() != null) {
+ limit.getOffset().accept(this, context);
+ }
+ if (limit.getRowCount() != null) {
+ limit.getRowCount().accept(this, context);
+ }
+ if (limit.getByExpressions() != null) {
+ limit.getByExpressions().accept(this, context);
+ }
+ }
+ return null;
+ }
+
+ default T visitPreferringClause(PreferringClause preferringClause, S context) {
+ if (preferringClause != null) {
+ if (preferringClause.getPreferring() != null) {
+ preferringClause.getPreferring().accept(this, context);
+ }
+ if (preferringClause.getPartitionBy() != null) {
+ for (Expression expression : preferringClause.getPartitionBy()) {
+ expression.accept(this, context);
+ }
+ }
+ }
+ return null;
+ }
+
+ default T visitUpdateSets(List updateSets, S context) {
+ if (updateSets != null) {
+ for (UpdateSet updateSet : updateSets) {
+ for (Column column : updateSet.getColumns()) {
+ column.accept(this, context);
+ }
+ for (Expression value : updateSet.getValues()) {
+ value.accept(this, context);
+ }
+ }
+ }
+ return null;
+ }
+
+ default T visit(GroupByElement groupBy, S context) {
+ if (groupBy != null) {
+ for (Expression expression : groupBy.getGroupByExpressionList()) {
+ expression.accept(this, context);
+ }
+ if (!groupBy.getGroupingSets().isEmpty()) {
+ for (ExpressionList> expressionList : groupBy.getGroupingSets()) {
+ expressionList.accept(this, context);
+ }
+ }
+ }
+ return null;
+ }
+
+ T visit(BitwiseRightShift bitwiseRightShift, S context);
+
+ default void visit(BitwiseRightShift bitwiseRightShift) {
+ this.visit(bitwiseRightShift, null);
+ }
+
+ T visit(BitwiseLeftShift bitwiseLeftShift, S context);
+
+ default void visit(BitwiseLeftShift bitwiseLeftShift) {
+ this.visit(bitwiseLeftShift, null);
+ }
+
+ T visit(NullValue nullValue, S context);
+
+ default void visit(NullValue nullValue) {
+ this.visit(nullValue, null);
+ }
+
+ T visit(Function function, S context);
+
+ default void visit(Function function) {
+ this.visit(function, null);
+ }
+
+ T visit(SignedExpression signedExpression, S context);
+
+ default void visit(SignedExpression signedExpression) {
+ this.visit(signedExpression, null);
+ }
+
+ T visit(JdbcParameter jdbcParameter, S context);
-public interface ExpressionVisitor {
+ default void visit(JdbcParameter jdbcParameter) {
+ this.visit(jdbcParameter, null);
+ }
- void visit(BitwiseRightShift aThis);
+ T visit(JdbcNamedParameter jdbcNamedParameter, S context);
- void visit(BitwiseLeftShift aThis);
+ default void visit(JdbcNamedParameter jdbcNamedParameter) {
+ this.visit(jdbcNamedParameter, null);
+ }
- void visit(NullValue nullValue);
+ T visit(DoubleValue doubleValue, S context);
- void visit(Function function);
+ default void visit(DoubleValue doubleValue) {
+ this.visit(doubleValue, null);
+ }
- void visit(SignedExpression signedExpression);
+ T visit(LongValue longValue, S context);
- void visit(JdbcParameter jdbcParameter);
+ default void visit(LongValue longValue) {
+ this.visit(longValue, null);
+ }
- void visit(JdbcNamedParameter jdbcNamedParameter);
+ T visit(HexValue hexValue, S context);
- void visit(DoubleValue doubleValue);
+ default void visit(HexValue hexValue) {
+ this.visit(hexValue, null);
+ }
- void visit(LongValue longValue);
+ T visit(DateValue dateValue, S context);
- void visit(HexValue hexValue);
+ default void visit(DateValue dateValue) {
+ this.visit(dateValue, null);
+ }
- void visit(DateValue dateValue);
+ T visit(TimeValue timeValue, S context);
- void visit(TimeValue timeValue);
+ default void visit(TimeValue timeValue) {
+ this.visit(timeValue, null);
+ }
- void visit(TimestampValue timestampValue);
+ T visit(TimestampValue timestampValue, S context);
- void visit(Parenthesis parenthesis);
+ default void visit(TimestampValue timestampValue) {
+ this.visit(timestampValue, null);
+ }
- void visit(StringValue stringValue);
+ T visit(StringValue stringValue, S context);
- void visit(Addition addition);
+ default void visit(StringValue stringValue) {
+ this.visit(stringValue, null);
+ }
- void visit(Division division);
+ T visit(BooleanValue booleanValue, S context);
- void visit(IntegerDivision division);
+ default void visit(BooleanValue booleanValue) {
+ this.visit(booleanValue, null);
+ }
- void visit(Multiplication multiplication);
+ T visit(Addition addition, S context);
- void visit(Subtraction subtraction);
+ default void visit(Addition addition) {
+ this.visit(addition, null);
+ }
- void visit(AndExpression andExpression);
+ T visit(Division division, S context);
- void visit(OrExpression orExpression);
+ default void visit(Division division) {
+ this.visit(division, null);
+ }
- void visit(XorExpression orExpression);
+ T visit(IntegerDivision integerDivision, S context);
- void visit(Between between);
+ default void visit(IntegerDivision integerDivision) {
+ this.visit(integerDivision, null);
+ }
- void visit(EqualsTo equalsTo);
+ T visit(Multiplication multiplication, S context);
- void visit(GreaterThan greaterThan);
+ default void visit(Multiplication multiplication) {
+ this.visit(multiplication, null);
+ }
- void visit(GreaterThanEquals greaterThanEquals);
+ T visit(Subtraction subtraction, S context);
- void visit(InExpression inExpression);
+ default void visit(Subtraction subtraction) {
+ this.visit(subtraction, null);
+ }
- void visit(FullTextSearch fullTextSearch);
+ T visit(AndExpression andExpression, S context);
- void visit(IsNullExpression isNullExpression);
+ default void visit(AndExpression andExpression) {
+ this.visit(andExpression, null);
+ }
- void visit(IsBooleanExpression isBooleanExpression);
+ T visit(OrExpression orExpression, S context);
- void visit(LikeExpression likeExpression);
+ default void visit(OrExpression orExpression) {
+ this.visit(orExpression, null);
+ }
- void visit(MinorThan minorThan);
+ T visit(XorExpression xorExpression, S context);
- void visit(MinorThanEquals minorThanEquals);
+ default void visit(XorExpression xorExpression) {
+ this.visit(xorExpression, null);
+ }
- void visit(NotEqualsTo notEqualsTo);
+ T visit(Between between, S context);
- void visit(Column tableColumn);
+ default void visit(Between between) {
+ this.visit(between, null);
+ }
- void visit(SubSelect subSelect);
+ T visit(OverlapsCondition overlapsCondition, S context);
- void visit(CaseExpression caseExpression);
+ default void visit(OverlapsCondition overlapsCondition) {
+ this.visit(overlapsCondition, null);
+ }
- void visit(WhenClause whenClause);
+ T visit(EqualsTo equalsTo, S context);
- void visit(ExistsExpression existsExpression);
+ default void visit(EqualsTo equalsTo) {
+ this.visit(equalsTo, null);
+ }
- void visit(AnyComparisonExpression anyComparisonExpression);
+ T visit(GreaterThan greaterThan, S context);
- void visit(Concat concat);
+ default void visit(GreaterThan greaterThan) {
+ this.visit(greaterThan, null);
+ }
- void visit(Matches matches);
+ T visit(GreaterThanEquals greaterThanEquals, S context);
- void visit(BitwiseAnd bitwiseAnd);
+ default void visit(GreaterThanEquals greaterThanEquals) {
+ this.visit(greaterThanEquals, null);
+ }
- void visit(BitwiseOr bitwiseOr);
+ T visit(InExpression inExpression, S context);
- void visit(BitwiseXor bitwiseXor);
+ default void visit(InExpression inExpression) {
+ this.visit(inExpression, null);
+ }
- void visit(CastExpression cast);
+ T visit(IncludesExpression includesExpression, S context);
- void visit(TryCastExpression cast);
+ default void visit(IncludesExpression includesExpression) {
+ this.visit(includesExpression, null);
+ }
- void visit(Modulo modulo);
+ T visit(ExcludesExpression excludesExpression, S context);
- void visit(AnalyticExpression aexpr);
+ default void visit(ExcludesExpression excludesExpression) {
+ this.visit(excludesExpression, null);
+ }
- void visit(ExtractExpression eexpr);
+ T visit(FullTextSearch fullTextSearch, S context);
- void visit(IntervalExpression iexpr);
+ default void visit(FullTextSearch fullTextSearch) {
+ this.visit(fullTextSearch, null);
+ }
- void visit(OracleHierarchicalExpression oexpr);
+ T visit(IsNullExpression isNullExpression, S context);
- void visit(RegExpMatchOperator rexpr);
+ default void visit(IsNullExpression isNullExpression) {
+ this.visit(isNullExpression, null);
+ }
- void visit(JsonExpression jsonExpr);
+ T visit(IsBooleanExpression isBooleanExpression, S context);
- void visit(JsonOperator jsonExpr);
+ default void visit(IsBooleanExpression isBooleanExpression) {
+ this.visit(isBooleanExpression, null);
+ }
- void visit(RegExpMySQLOperator regExpMySQLOperator);
+ T visit(IsUnknownExpression isUnknownExpression, S context);
- void visit(UserVariable var);
+ default void visit(IsUnknownExpression isUnknownExpression) {
+ this.visit(isUnknownExpression, null);
+ }
- void visit(NumericBind bind);
+ T visit(LikeExpression likeExpression, S context);
- void visit(KeepExpression aexpr);
+ default void visit(LikeExpression likeExpression) {
+ this.visit(likeExpression, null);
+ }
- void visit(MySQLGroupConcat groupConcat);
+ T visit(MinorThan minorThan, S context);
- void visit(ValueListExpression valueList);
+ default void visit(MinorThan minorThan) {
+ this.visit(minorThan, null);
+ }
- void visit(RowConstructor rowConstructor);
+ T visit(MinorThanEquals minorThanEquals, S context);
- void visit(RowGetExpression rowGetExpression);
+ default void visit(MinorThanEquals minorThanEquals) {
+ this.visit(minorThanEquals, null);
+ }
- void visit(OracleHint hint);
+ T visit(NotEqualsTo notEqualsTo, S context);
- void visit(TimeKeyExpression timeKeyExpression);
+ default void visit(NotEqualsTo notEqualsTo) {
+ this.visit(notEqualsTo, null);
+ }
- void visit(DateTimeLiteralExpression literal);
+ T visit(DoubleAnd doubleAnd, S context);
- void visit(NotExpression aThis);
+ default void visit(DoubleAnd doubleAnd) {
+ this.visit(doubleAnd, null);
+ }
- void visit(NextValExpression aThis);
+ T visit(Contains contains, S context);
- void visit(CollateExpression aThis);
+ default void visit(Contains contains) {
+ this.visit(contains, null);
+ }
- void visit(SimilarToExpression aThis);
+ T visit(ContainedBy containedBy, S context);
- void visit(ArrayExpression aThis);
+ default void visit(ContainedBy containedBy) {
+ this.visit(containedBy, null);
+ }
- void visit(ArrayConstructor aThis);
+ T visit(ParenthesedSelect select, S context);
- void visit(VariableAssignment aThis);
+ T visit(Column column, S context);
- void visit(XMLSerializeExpr aThis);
+ default void visit(Column column) {
+ this.visit(column, null);
+ }
- void visit(TimezoneExpression aThis);
+ T visit(CaseExpression caseExpression, S context);
- void visit(JsonAggregateFunction aThis);
+ default void visit(CaseExpression caseExpression) {
+ this.visit(caseExpression, null);
+ }
- void visit(JsonFunction aThis);
+ T visit(WhenClause whenClause, S context);
- void visit(ConnectByRootOperator aThis);
+ default void visit(WhenClause whenClause) {
+ this.visit(whenClause, null);
+ }
- void visit(OracleNamedFunctionParameter aThis);
+ T visit(ExistsExpression existsExpression, S context);
- void visit(AllColumns allColumns);
+ default void visit(ExistsExpression existsExpression) {
+ this.visit(existsExpression, null);
+ }
- void visit(AllTableColumns allTableColumns);
+ T visit(MemberOfExpression memberOfExpression, S context);
- void visit(AllValue allValue);
+ default void visit(MemberOfExpression memberOfExpression) {
+ this.visit(memberOfExpression, null);
+ }
- void visit(IsDistinctExpression isDistinctExpression);
+ T visit(AnyComparisonExpression anyComparisonExpression, S context);
- void visit(GeometryDistance geometryDistance);
+ default void visit(AnyComparisonExpression anyComparisonExpression) {
+ this.visit(anyComparisonExpression, null);
+ }
+
+ T visit(Concat concat, S context);
+
+ default void visit(Concat concat) {
+ this.visit(concat, null);
+ }
+
+ T visit(Matches matches, S context);
+
+ default void visit(Matches matches) {
+ this.visit(matches, null);
+ }
+
+ T visit(BitwiseAnd bitwiseAnd, S context);
+
+ default void visit(BitwiseAnd bitwiseAnd) {
+ this.visit(bitwiseAnd, null);
+ }
+
+ T visit(BitwiseOr bitwiseOr, S context);
+
+ default void visit(BitwiseOr bitwiseOr) {
+ this.visit(bitwiseOr, null);
+ }
+
+ T visit(BitwiseXor bitwiseXor, S context);
+
+ default void visit(BitwiseXor bitwiseXor) {
+ this.visit(bitwiseXor, null);
+ }
+
+ T visit(CastExpression castExpression, S context);
+
+ default void visit(CastExpression castExpression) {
+ this.visit(castExpression, null);
+ }
+
+ T visit(Modulo modulo, S context);
+
+ default void visit(Modulo modulo) {
+ this.visit(modulo, null);
+ }
+
+ T visit(AnalyticExpression analyticExpression, S context);
+
+ default void visit(AnalyticExpression analyticExpression) {
+ this.visit(analyticExpression, null);
+ }
+
+ T visit(ExtractExpression extractExpression, S context);
+
+ default void visit(ExtractExpression extractExpression) {
+ this.visit(extractExpression, null);
+ }
+
+ T visit(IntervalExpression intervalExpression, S context);
+
+ default void visit(IntervalExpression intervalExpression) {
+ this.visit(intervalExpression, null);
+ }
+
+ T visit(OracleHierarchicalExpression hierarchicalExpression, S context);
+
+ default void visit(OracleHierarchicalExpression hierarchicalExpression) {
+ this.visit(hierarchicalExpression, null);
+ }
+
+ T visit(RegExpMatchOperator regExpMatchOperator, S context);
+
+ default void visit(RegExpMatchOperator regExpMatchOperator) {
+ this.visit(regExpMatchOperator, null);
+ }
+
+ T visit(JsonExpression jsonExpression, S context);
+
+ default void visit(JsonExpression jsonExpression) {
+ this.visit(jsonExpression, null);
+ }
+
+ T visit(JsonOperator jsonOperator, S context);
+
+ default void visit(JsonOperator jsonOperator) {
+ this.visit(jsonOperator, null);
+ }
+
+ T visit(UserVariable userVariable, S context);
+
+ default void visit(UserVariable userVariable) {
+ this.visit(userVariable, null);
+ }
+
+ T visit(NumericBind numericBind, S context);
+
+ default void visit(NumericBind numericBind) {
+ this.visit(numericBind, null);
+ }
+
+ T visit(KeepExpression keepExpression, S context);
+
+ default void visit(KeepExpression keepExpression) {
+ this.visit(keepExpression, null);
+ }
+
+ T visit(MySQLGroupConcat groupConcat, S context);
+
+ default void visit(MySQLGroupConcat groupConcat) {
+ this.visit(groupConcat, null);
+ }
+
+ T visit(ExpressionList extends Expression> expressionList, S context);
+
+ default void visit(ExpressionList extends Expression> expressionList) {
+ this.visit(expressionList, null);
+ }
+
+ T visit(RowConstructor extends Expression> rowConstructor, S context);
+
+ default void visit(RowConstructor extends Expression> rowConstructor) {
+ this.visit(rowConstructor, null);
+ }
+
+ T visit(RowGetExpression rowGetExpression, S context);
+
+ default void visit(RowGetExpression rowGetExpression) {
+ this.visit(rowGetExpression, null);
+ }
+
+ T visit(OracleHint hint, S context);
+
+ default void visit(OracleHint hint) {
+ this.visit(hint, null);
+ }
+
+ T visit(TimeKeyExpression timeKeyExpression, S context);
+
+ default void visit(TimeKeyExpression timeKeyExpression) {
+ this.visit(timeKeyExpression, null);
+ }
+
+ T visit(DateTimeLiteralExpression dateTimeLiteralExpression, S context);
+
+ default void visit(DateTimeLiteralExpression dateTimeLiteralExpression) {
+ this.visit(dateTimeLiteralExpression, null);
+ }
+
+ T visit(NotExpression notExpression, S context);
+
+ default void visit(NotExpression notExpression) {
+ this.visit(notExpression, null);
+ }
+
+ T visit(NextValExpression nextValExpression, S context);
+
+ default void visit(NextValExpression nextValExpression) {
+ this.visit(nextValExpression, null);
+ }
+
+ T visit(CollateExpression collateExpression, S context);
+
+ default void visit(CollateExpression collateExpression) {
+ this.visit(collateExpression, null);
+ }
+
+ T visit(SimilarToExpression similarToExpression, S context);
+
+ default void visit(SimilarToExpression similarToExpression) {
+ this.visit(similarToExpression, null);
+ }
+
+ T visit(ArrayExpression arrayExpression, S context);
+
+ default void visit(ArrayExpression arrayExpression) {
+ this.visit(arrayExpression, null);
+ }
+
+ T visit(ArrayConstructor arrayConstructor, S context);
+
+ default void visit(ArrayConstructor arrayConstructor) {
+ this.visit(arrayConstructor, null);
+ }
+
+ T visit(VariableAssignment variableAssignment, S context);
+
+ default void visit(VariableAssignment variableAssignment) {
+ this.visit(variableAssignment, null);
+ }
+
+ T visit(XMLSerializeExpr xmlSerializeExpr, S context);
+
+ default void visit(XMLSerializeExpr xmlSerializeExpr) {
+ this.visit(xmlSerializeExpr, null);
+ }
+
+ T visit(TimezoneExpression timezoneExpression, S context);
+
+ default void visit(TimezoneExpression timezoneExpression) {
+ this.visit(timezoneExpression, null);
+ }
+
+ T visit(JsonAggregateFunction jsonAggregateFunction, S context);
+
+ default void visit(JsonAggregateFunction jsonAggregateFunction) {
+ this.visit(jsonAggregateFunction, null);
+ }
+
+ T visit(JsonFunction jsonFunction, S context);
+
+ default void visit(JsonFunction jsonFunction) {
+ this.visit(jsonFunction, null);
+ }
+
+ T visit(ConnectByRootOperator connectByRootOperator, S context);
+
+ default void visit(ConnectByRootOperator connectByRootOperator) {
+ this.visit(connectByRootOperator, null);
+ }
+
+ T visit(ConnectByPriorOperator connectByPriorOperator, S context);
+
+ default void visit(ConnectByPriorOperator connectByPriorOperator) {
+ this.visit(connectByPriorOperator, null);
+ }
+
+ T visit(OracleNamedFunctionParameter oracleNamedFunctionParameter, S context);
+
+ default void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter) {
+ this.visit(oracleNamedFunctionParameter, null);
+ }
+
+ T visit(AllColumns allColumns, S context);
+
+ T visit(FunctionAllColumns functionColumns, S context);
+
+ default void visit(AllColumns allColumns) {
+ this.visit(allColumns, null);
+ }
+
+ T visit(AllTableColumns allTableColumns, S context);
+
+ default void visit(AllTableColumns allTableColumns) {
+ this.visit(allTableColumns, null);
+ }
+
+ T visit(AllValue allValue, S context);
+
+ default void visit(AllValue allValue) {
+ this.visit(allValue, null);
+ }
+
+ T visit(IsDistinctExpression isDistinctExpression, S context);
+
+ default void visit(IsDistinctExpression isDistinctExpression) {
+ this.visit(isDistinctExpression, null);
+ }
+
+ T visit(GeometryDistance geometryDistance, S context);
+
+ default void visit(GeometryDistance geometryDistance) {
+ this.visit(geometryDistance, null);
+ }
+
+ T visit(Select select, S context);
+
+ T visit(TranscodingFunction transcodingFunction, S context);
+
+ default void visit(TranscodingFunction transcodingFunction) {
+ this.visit(transcodingFunction, null);
+ }
+
+ T visit(TrimFunction trimFunction, S context);
+
+ default void visit(TrimFunction trimFunction) {
+ this.visit(trimFunction, null);
+ }
+
+ T visit(RangeExpression rangeExpression, S context);
+
+ default void visit(RangeExpression rangeExpression) {
+ this.visit(rangeExpression, null);
+ }
+
+ T visit(TSQLLeftJoin tsqlLeftJoin, S context);
+
+ default void visit(TSQLLeftJoin tsqlLeftJoin) {
+ this.visit(tsqlLeftJoin, null);
+ }
+
+ T visit(TSQLRightJoin tsqlRightJoin, S context);
+
+ default void visit(TSQLRightJoin tsqlRightJoin) {
+ this.visit(tsqlRightJoin, null);
+ }
+
+ T visit(StructType structType, S context);
+
+ default void visit(StructType structType) {
+ this.visit(structType, null);
+ }
+
+ T visit(LambdaExpression lambdaExpression, S context);
+
+ default void visit(LambdaExpression lambdaExpression) {
+ this.visit(lambdaExpression, null);
+ }
+
+ T visit(HighExpression highExpression, S context);
+
+ default void visit(HighExpression highExpression) {
+ this.visit(highExpression, null);
+ }
+
+ T visit(LowExpression lowExpression, S context);
+
+ default void visit(LowExpression lowExpression) {
+ this.visit(lowExpression, null);
+ }
+
+ T visit(Plus plus, S context);
+
+ default void visit(Plus plus) {
+ this.visit(plus, null);
+ }
+
+ T visit(PriorTo priorTo, S context);
+
+ default void visit(PriorTo priorTo) {
+ this.visit(priorTo, null);
+ }
+
+ T visit(Inverse inverse, S context);
+
+ default void visit(Inverse inverse) {
+ this.visit(inverse, null);
+ }
+
+ T visit(CosineSimilarity cosineSimilarity, S context);
+
+ T visit(FromQuery fromQuery, S context);
}
diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java
index 6800f325b..96d80d514 100644
--- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java
+++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java
@@ -9,636 +9,835 @@
*/
package net.sf.jsqlparser.expression;
-import net.sf.jsqlparser.expression.operators.arithmetic.*;
+import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
+import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
+import net.sf.jsqlparser.expression.operators.arithmetic.Division;
+import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
+import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
+import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
+import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
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.*;
+import net.sf.jsqlparser.expression.operators.relational.Between;
+import net.sf.jsqlparser.expression.operators.relational.ContainedBy;
+import net.sf.jsqlparser.expression.operators.relational.Contains;
+import net.sf.jsqlparser.expression.operators.relational.CosineSimilarity;
+import net.sf.jsqlparser.expression.operators.relational.DoubleAnd;
+import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
+import net.sf.jsqlparser.expression.operators.relational.ExcludesExpression;
+import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.FullTextSearch;
+import net.sf.jsqlparser.expression.operators.relational.GeometryDistance;
+import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
+import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
+import net.sf.jsqlparser.expression.operators.relational.InExpression;
+import net.sf.jsqlparser.expression.operators.relational.IncludesExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsBooleanExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsDistinctExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsUnknownExpression;
+import net.sf.jsqlparser.expression.operators.relational.JsonOperator;
+import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
+import net.sf.jsqlparser.expression.operators.relational.Matches;
+import net.sf.jsqlparser.expression.operators.relational.MemberOfExpression;
+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.expression.operators.relational.Plus;
+import net.sf.jsqlparser.expression.operators.relational.PriorTo;
+import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
+import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
+import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin;
+import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin;
import net.sf.jsqlparser.schema.Column;
-import net.sf.jsqlparser.statement.create.table.ColumnDefinition;
+import net.sf.jsqlparser.statement.piped.FromQuery;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
-import net.sf.jsqlparser.statement.select.ExpressionListItem;
-import net.sf.jsqlparser.statement.select.FunctionItem;
+import net.sf.jsqlparser.statement.select.FunctionAllColumns;
import net.sf.jsqlparser.statement.select.OrderByElement;
+import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.Pivot;
import net.sf.jsqlparser.statement.select.PivotVisitor;
import net.sf.jsqlparser.statement.select.PivotXml;
-import net.sf.jsqlparser.statement.select.SelectExpressionItem;
+import net.sf.jsqlparser.statement.select.Select;
+import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.statement.select.SelectItemVisitor;
import net.sf.jsqlparser.statement.select.SelectVisitor;
-import net.sf.jsqlparser.statement.select.SubSelect;
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"})
-public class ExpressionVisitorAdapter implements ExpressionVisitor, ItemsListVisitor, PivotVisitor, SelectItemVisitor {
+public class ExpressionVisitorAdapter
+ implements ExpressionVisitor, PivotVisitor, SelectItemVisitor {
+
+ private SelectVisitor selectVisitor;
+
+ public ExpressionVisitorAdapter(SelectVisitor selectVisitor) {
+ this.selectVisitor = selectVisitor;
+ }
- private SelectVisitor selectVisitor;
+ public ExpressionVisitorAdapter() {
+ this.selectVisitor = null;
+ }
- public SelectVisitor getSelectVisitor() {
+ public SelectVisitor getSelectVisitor() {
return selectVisitor;
}
- public void setSelectVisitor(SelectVisitor selectVisitor) {
+ public ExpressionVisitorAdapter setSelectVisitor(SelectVisitor selectVisitor) {
this.selectVisitor = selectVisitor;
+ return this;
}
@Override
- public void visit(NullValue value) {
-
+ public T visit(NullValue nullValue, S context) {
+ return applyExpression(nullValue, context);
}
@Override
- public void visit(Function function) {
+ public T visit(Function function, S context) {
+ ArrayList subExpressions = new ArrayList<>();
if (function.getParameters() != null) {
- function.getParameters().accept(this);
+ subExpressions.addAll(function.getParameters());
}
if (function.getKeep() != null) {
- function.getKeep().accept(this);
+ subExpressions.add(function.getKeep());
}
if (function.getOrderByElements() != null) {
for (OrderByElement orderByElement : function.getOrderByElements()) {
- orderByElement.getExpression().accept(this);
+ subExpressions.add(orderByElement.getExpression());
}
}
+ return visitExpressions(function, context, subExpressions);
}
@Override
- public void visit(SignedExpression expr) {
- expr.getExpression().accept(this);
+ public T visit(SignedExpression signedExpression, S context) {
+ return signedExpression.getExpression().accept(this, context);
}
@Override
- public void visit(JdbcParameter parameter) {
-
+ public T visit(JdbcParameter jdbcParameter, S context) {
+ return applyExpression(jdbcParameter, context);
}
@Override
- public void visit(JdbcNamedParameter parameter) {
-
+ public T visit(JdbcNamedParameter jdbcNamedParameter, S context) {
+ return applyExpression(jdbcNamedParameter, context);
}
@Override
- public void visit(DoubleValue value) {
-
+ public T visit(DoubleValue doubleValue, S context) {
+ return applyExpression(doubleValue, context);
}
@Override
- public void visit(LongValue value) {
+ public T visit(LongValue longValue, S context) {
+ return applyExpression(longValue, context);
+ }
+ @Override
+ public T visit(DateValue dateValue, S context) {
+ return applyExpression(dateValue, context);
}
@Override
- public void visit(DateValue value) {
+ public T visit(TimeValue timeValue, S context) {
+ return applyExpression(timeValue, context);
+ }
+ @Override
+ public T visit(TimestampValue timestampValue, S context) {
+ return applyExpression(timestampValue, context);
}
@Override
- public void visit(TimeValue value) {
+ public T visit(StringValue stringValue, S context) {
+ return applyExpression(stringValue, context);
+ }
+ @Override
+ public T visit(BooleanValue booleanValue, S context) {
+ return applyExpression(booleanValue, context);
}
@Override
- public void visit(TimestampValue value) {
+ public T visit(Addition addition, S context) {
+ return visitBinaryExpression(addition, context);
+ }
+ @Override
+ public T visit(Division division, S context) {
+ return visitBinaryExpression(division, context);
}
@Override
- public void visit(Parenthesis parenthesis) {
- parenthesis.getExpression().accept(this);
+ public T visit(IntegerDivision integerDivision, S context) {
+ return visitBinaryExpression(integerDivision, context);
}
@Override
- public void visit(StringValue value) {
+ public T visit(Multiplication multiplication, S context) {
+ return visitBinaryExpression(multiplication, context);
+ }
+ @Override
+ public T visit(Subtraction subtraction, S context) {
+ return visitBinaryExpression(subtraction, context);
}
@Override
- public void visit(Addition expr) {
- visitBinaryExpression(expr);
+ public T visit(AndExpression andExpression, S context) {
+ return visitBinaryExpression(andExpression, context);
}
@Override
- public void visit(Division expr) {
- visitBinaryExpression(expr);
+ public T visit(OrExpression orExpression, S context) {
+ return visitBinaryExpression(orExpression, context);
}
@Override
- public void visit(IntegerDivision expr) {
- visitBinaryExpression(expr);
+ public T visit(XorExpression xorExpression, S context) {
+ return visitBinaryExpression(xorExpression, context);
}
@Override
- public void visit(Multiplication expr) {
- visitBinaryExpression(expr);
+ public T visit(Between between, S context) {
+ return visitExpressions(between, context, between.getLeftExpression(),
+ between.getBetweenExpressionStart(), between.getBetweenExpressionEnd());
}
+ public T visit(OverlapsCondition overlapsCondition, S context) {
+ return visitExpressions(overlapsCondition, context, overlapsCondition.getLeft(),
+ overlapsCondition.getRight());
+ }
+
+
@Override
- public void visit(Subtraction expr) {
- visitBinaryExpression(expr);
+ public T visit(EqualsTo equalsTo, S context) {
+ return visitBinaryExpression(equalsTo, context);
}
@Override
- public void visit(AndExpression expr) {
- visitBinaryExpression(expr);
+ public T visit(GreaterThan greaterThan, S context) {
+ return visitBinaryExpression(greaterThan, context);
}
@Override
- public void visit(OrExpression expr) {
- visitBinaryExpression(expr);
+ public T visit(GreaterThanEquals greaterThanEquals, S context) {
+ return visitBinaryExpression(greaterThanEquals, context);
}
@Override
- public void visit(XorExpression expr) {
- visitBinaryExpression(expr);
+ public T visit(InExpression inExpression, S context) {
+ return visitExpressions(inExpression, context, inExpression.getLeftExpression(),
+ inExpression.getRightExpression());
}
@Override
- public void visit(Between expr) {
- expr.getLeftExpression().accept(this);
- expr.getBetweenExpressionStart().accept(this);
- expr.getBetweenExpressionEnd().accept(this);
+ public T visit(IncludesExpression includesExpression, S context) {
+ return visitExpressions(includesExpression, context, includesExpression.getLeftExpression(),
+ includesExpression.getRightExpression());
}
@Override
- public void visit(EqualsTo expr) {
- visitBinaryExpression(expr);
+ public T visit(ExcludesExpression excludesExpression, S context) {
+ return visitExpressions(excludesExpression, context, excludesExpression.getLeftExpression(),
+ excludesExpression.getRightExpression());
}
@Override
- public void visit(GreaterThan expr) {
- visitBinaryExpression(expr);
+ public T visit(IsNullExpression isNullExpression, S context) {
+ return isNullExpression.getLeftExpression().accept(this, context);
}
@Override
- public void visit(GreaterThanEquals expr) {
- visitBinaryExpression(expr);
+ public T visit(FullTextSearch fullTextSearch, S context) {
+ ArrayList subExpressions = new ArrayList<>(fullTextSearch.getMatchColumns());
+ subExpressions.add(fullTextSearch.getAgainstValue());
+ return visitExpressions(fullTextSearch, context, subExpressions);
}
@Override
- public void visit(InExpression expr) {
- if (expr.getLeftExpression() != null) {
- expr.getLeftExpression().accept(this);
- }
- if (expr.getRightExpression() != null) {
- expr.getRightExpression().accept(this);
- } else if (expr.getRightItemsList() != null) {
- expr.getRightItemsList().accept(this);
- }
+ public T visit(IsBooleanExpression isBooleanExpression, S context) {
+ return isBooleanExpression.getLeftExpression().accept(this, context);
}
@Override
- public void visit(IsNullExpression expr) {
- expr.getLeftExpression().accept(this);
+ public T visit(IsUnknownExpression isUnknownExpression, S context) {
+ return isUnknownExpression.getLeftExpression().accept(this, context);
}
@Override
- public void visit(FullTextSearch expr) {
- for (Column col : expr.getMatchColumns()) {
- col.accept(this);
- }
+ public T visit(LikeExpression likeExpression, S context) {
+ return visitBinaryExpression(likeExpression, context);
}
@Override
- public void visit(IsBooleanExpression expr) {
- expr.getLeftExpression().accept(this);
+ public T visit(MinorThan minorThan, S context) {
+ return visitBinaryExpression(minorThan, context);
}
@Override
- public void visit(LikeExpression expr) {
- visitBinaryExpression(expr);
+ public T visit(MinorThanEquals minorThanEquals, S context) {
+ return visitBinaryExpression(minorThanEquals, context);
}
@Override
- public void visit(MinorThan expr) {
- visitBinaryExpression(expr);
+ public T visit(NotEqualsTo notEqualsTo, S context) {
+ return visitBinaryExpression(notEqualsTo, context);
}
@Override
- public void visit(MinorThanEquals expr) {
- visitBinaryExpression(expr);
+ public T visit(DoubleAnd doubleAnd, S context) {
+ return visitBinaryExpression(doubleAnd, context);
}
@Override
- public void visit(NotEqualsTo expr) {
- visitBinaryExpression(expr);
+ public T visit(Contains contains, S context) {
+ return visitBinaryExpression(contains, context);
}
@Override
- public void visit(Column column) {
+ public T visit(ContainedBy containedBy, S context) {
+ return visitBinaryExpression(containedBy, context);
+ }
+ @Override
+ public T visit(Column column, S context) {
+ return applyExpression(column, context);
}
@Override
- public void visit(SubSelect subSelect) {
- if (selectVisitor != null) {
- if (subSelect.getWithItemsList() != null) {
- for (WithItem item : subSelect.getWithItemsList()) {
- item.accept(selectVisitor);
- }
- }
- subSelect.getSelectBody().accept(selectVisitor);
- }
- if (subSelect.getPivot() != null) {
- subSelect.getPivot().accept(this);
+ public T visit(ParenthesedSelect select, S context) {
+ visit((Select) select, context);
+ if (select.getPivot() != null) {
+ select.getPivot().accept(this, context);
}
+ return null;
}
@Override
- public void visit(CaseExpression expr) {
- if (expr.getSwitchExpression() != null) {
- expr.getSwitchExpression().accept(this);
- }
- for (Expression x : expr.getWhenClauses()) {
- x.accept(this);
+ public T visit(CaseExpression caseExpression, S context) {
+ ArrayList subExpressions = new ArrayList<>();
+
+ if (caseExpression.getSwitchExpression() != null) {
+ subExpressions.add(caseExpression.getSwitchExpression());
}
- if (expr.getElseExpression() != null) {
- expr.getElseExpression().accept(this);
+ subExpressions.addAll(caseExpression.getWhenClauses());
+ if (caseExpression.getElseExpression() != null) {
+ subExpressions.add(caseExpression.getElseExpression());
}
+ return visitExpressions(caseExpression, context, subExpressions);
}
@Override
- public void visit(WhenClause expr) {
- expr.getWhenExpression().accept(this);
- expr.getThenExpression().accept(this);
+ public T visit(WhenClause whenClause, S context) {
+ return visitExpressions(whenClause, context, whenClause.getWhenExpression(),
+ whenClause.getThenExpression());
}
@Override
- public void visit(ExistsExpression expr) {
- expr.getRightExpression().accept(this);
+ public T visit(ExistsExpression existsExpression, S context) {
+ return existsExpression.getRightExpression().accept(this, context);
}
-
- @Override
- public void visit(AnyComparisonExpression expr) {
+ @Override
+ public T visit(MemberOfExpression memberOfExpression, S context) {
+ return memberOfExpression.getRightExpression().accept(this, context);
}
@Override
- public void visit(Concat expr) {
- visitBinaryExpression(expr);
+ public