From 6493f7e26d989d5bfccb793f2fd1b038afda4ed7 Mon Sep 17 00:00:00 2001
From: jakobbraun
Date: Tue, 10 Nov 2020 08:30:44 +0100
Subject: [PATCH] Refactor/95 value expression visitor (#101)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* #95 Refactored `ValueExpressionVisitor`
* removed TreeNode structure; combined BooleanExpressionRenderer and ValueExpressionRenderer
Co-authored-by: Sebastian Bär
---
doc/changes/changes_4.3.1.md | 1 +
doc/diagrams/interfaces.puml | 13 +
.../com/exasol/sql/UnnamedPlaceholder.java | 5 +-
.../java/com/exasol/sql/ValueTableRow.java | 11 +-
.../sql/dml/merge/MergeUpdateClause.java | 20 +-
.../dml/merge/rendering/MergeRenderer.java | 9 +-
.../dql/select/rendering/SelectRenderer.java | 9 +-
.../expression/AbstractBooleanExpression.java | 39 +--
.../expression/AbstractValueExpression.java | 15 -
.../java/com/exasol/sql/expression/And.java | 29 +-
.../BinaryArithmeticExpression.java | 10 +-
.../expression/BooleanExpressionVisitor.java | 7 +-
.../exasol/sql/expression/BooleanTerm.java | 1 +
.../sql/expression/ColumnReference.java | 14 +-
.../exasol/sql/expression/DefaultValue.java | 2 +-
.../exasol/sql/expression/ExpressionTerm.java | 25 +-
.../java/com/exasol/sql/expression/Not.java | 28 +-
.../java/com/exasol/sql/expression/Or.java | 27 +-
.../sql/expression/ValueExpression.java | 4 +-
.../expression/ValueExpressionVisitor.java | 32 +--
.../comparison/AbstractComparison.java | 15 +-
.../expression/function/AbstractFunction.java | 30 +-
.../sql/expression/function/Function.java | 9 +-
.../expression/function/FunctionVisitor.java | 16 ++
.../function/exasol/CastExasolFunction.java | 11 +-
.../function/exasol/ExasolFunction.java | 8 +-
.../expression/function/exasol/ExasolUdf.java | 26 +-
.../expression/literal/AbstractLiteral.java | 14 +
.../{ => literal}/BigDecimalLiteral.java | 14 +-
.../{ => literal}/BooleanLiteral.java | 24 +-
.../{ => literal}/DoubleLiteral.java | 6 +-
.../{ => literal}/FloatLiteral.java | 6 +-
.../{ => literal}/IntegerLiteral.java | 6 +-
.../sql/expression/literal/Literal.java | 15 +
.../expression/literal/LiteralVisitor.java | 23 ++
.../expression/{ => literal}/LongLiteral.java | 6 +-
.../expression/{ => literal}/NullLiteral.java | 6 +-
.../{ => literal}/StringLiteral.java | 6 +-
.../rendering/AbstractExpressionRenderer.java | 32 +--
.../rendering/BooleanExpressionRenderer.java | 78 ------
.../rendering/ComparisonRenderer.java | 65 -----
.../rendering/ValueExpressionRenderer.java | 261 ++++++++++++------
.../rendering/AbstractFragmentRenderer.java | 24 +-
.../exasol/util/AbstractBottomUpTreeNode.java | 72 -----
.../java/com/exasol/util/AbstractTree.java | 47 ----
.../com/exasol/util/AbstractTreeNode.java | 46 ---
src/main/java/com/exasol/util/TreeNode.java | 85 ------
.../BooleanExpressionRenderResultMatcher.java | 64 -----
.../ValueExpressionRenderResultMatcher.java | 64 +++++
.../dml/merge/MergeMethodDefinitionTest.java | 2 +-
.../TestComparisonOperator.java | 4 +-
.../exasol/CastExasolFunctionTest.java | 6 +-
.../{ => literal}/DoubleLiteralTest.java | 2 +-
.../{ => literal}/FloatLiteralTest.java | 2 +-
.../{ => literal}/LongLiteralTest.java | 2 +-
.../{ => literal}/TestBigDecimalLiteral.java | 2 +-
.../{ => literal}/TestBooleanLiteral.java | 2 +-
.../{ => literal}/TestIntegerLiteral.java | 2 +-
.../{ => literal}/TestStringLiteral.java | 2 +-
.../TestBooleanExpressionRenderer.java | 6 +-
.../exasol/util/DummyBottomUpTreeNode.java | 11 -
.../java/com/exasol/util/DummyTreeNode.java | 7 -
.../util/TestAbstractBottomUpTreeNode.java | 139 ----------
.../com/exasol/util/TestAbstractTreeNode.java | 109 --------
64 files changed, 560 insertions(+), 1118 deletions(-)
create mode 100644 doc/diagrams/interfaces.puml
delete mode 100644 src/main/java/com/exasol/sql/expression/AbstractValueExpression.java
create mode 100644 src/main/java/com/exasol/sql/expression/function/FunctionVisitor.java
create mode 100644 src/main/java/com/exasol/sql/expression/literal/AbstractLiteral.java
rename src/main/java/com/exasol/sql/expression/{ => literal}/BigDecimalLiteral.java (65%)
rename src/main/java/com/exasol/sql/expression/{ => literal}/BooleanLiteral.java (86%)
rename src/main/java/com/exasol/sql/expression/{ => literal}/DoubleLiteral.java (82%)
rename src/main/java/com/exasol/sql/expression/{ => literal}/FloatLiteral.java (82%)
rename src/main/java/com/exasol/sql/expression/{ => literal}/IntegerLiteral.java (82%)
create mode 100644 src/main/java/com/exasol/sql/expression/literal/Literal.java
create mode 100644 src/main/java/com/exasol/sql/expression/literal/LiteralVisitor.java
rename src/main/java/com/exasol/sql/expression/{ => literal}/LongLiteral.java (82%)
rename src/main/java/com/exasol/sql/expression/{ => literal}/NullLiteral.java (68%)
rename src/main/java/com/exasol/sql/expression/{ => literal}/StringLiteral.java (84%)
delete mode 100644 src/main/java/com/exasol/sql/expression/rendering/BooleanExpressionRenderer.java
delete mode 100644 src/main/java/com/exasol/sql/expression/rendering/ComparisonRenderer.java
delete mode 100644 src/main/java/com/exasol/util/AbstractBottomUpTreeNode.java
delete mode 100644 src/main/java/com/exasol/util/AbstractTree.java
delete mode 100644 src/main/java/com/exasol/util/AbstractTreeNode.java
delete mode 100644 src/main/java/com/exasol/util/TreeNode.java
delete mode 100644 src/test/java/com/exasol/hamcrest/BooleanExpressionRenderResultMatcher.java
create mode 100644 src/test/java/com/exasol/hamcrest/ValueExpressionRenderResultMatcher.java
rename src/test/java/com/exasol/sql/expression/{ => comparison}/TestComparisonOperator.java (88%)
rename src/test/java/com/exasol/sql/expression/{ => literal}/DoubleLiteralTest.java (90%)
rename src/test/java/com/exasol/sql/expression/{ => literal}/FloatLiteralTest.java (90%)
rename src/test/java/com/exasol/sql/expression/{ => literal}/LongLiteralTest.java (91%)
rename src/test/java/com/exasol/sql/expression/{ => literal}/TestBigDecimalLiteral.java (92%)
rename src/test/java/com/exasol/sql/expression/{ => literal}/TestBooleanLiteral.java (97%)
rename src/test/java/com/exasol/sql/expression/{ => literal}/TestIntegerLiteral.java (90%)
rename src/test/java/com/exasol/sql/expression/{ => literal}/TestStringLiteral.java (87%)
delete mode 100644 src/test/java/com/exasol/util/DummyBottomUpTreeNode.java
delete mode 100644 src/test/java/com/exasol/util/DummyTreeNode.java
delete mode 100644 src/test/java/com/exasol/util/TestAbstractBottomUpTreeNode.java
delete mode 100644 src/test/java/com/exasol/util/TestAbstractTreeNode.java
diff --git a/doc/changes/changes_4.3.1.md b/doc/changes/changes_4.3.1.md
index 2eda4ffd..b247eec9 100644
--- a/doc/changes/changes_4.3.1.md
+++ b/doc/changes/changes_4.3.1.md
@@ -7,3 +7,4 @@ Code Name: Refactoring
* #98: Refactored comparison and like class structure
The refactoring changed the internal representation of the `Comparison`.
The public API from `BooleanTerm` did however not change.
+* #95: Refactored `ValueExpressionVisitor`
diff --git a/doc/diagrams/interfaces.puml b/doc/diagrams/interfaces.puml
new file mode 100644
index 00000000..82858337
--- /dev/null
+++ b/doc/diagrams/interfaces.puml
@@ -0,0 +1,13 @@
+@startuml
+interface ValueExpression
+interface BooleanExpression
+interface Function
+interface Comparison
+interface Literal
+
+ValueExpression <|-- BooleanExpression
+ValueExpression <|-- Function
+ValueExpression <|-- Literal
+BooleanExpression <|-- Comparison
+
+@enduml
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/UnnamedPlaceholder.java b/src/main/java/com/exasol/sql/UnnamedPlaceholder.java
index c01d3fca..5337f0be 100644
--- a/src/main/java/com/exasol/sql/UnnamedPlaceholder.java
+++ b/src/main/java/com/exasol/sql/UnnamedPlaceholder.java
@@ -1,11 +1,12 @@
package com.exasol.sql;
-import com.exasol.sql.expression.*;
+import com.exasol.sql.expression.ValueExpression;
+import com.exasol.sql.expression.ValueExpressionVisitor;
/**
* This class implements a nameless placeholder ("?") in an SQL statement
*/
-public class UnnamedPlaceholder extends AbstractValueExpression implements ValueExpression {
+public class UnnamedPlaceholder implements ValueExpression {
@Override
public void accept(final ValueExpressionVisitor visitor) {
visitor.visit(this);
diff --git a/src/main/java/com/exasol/sql/ValueTableRow.java b/src/main/java/com/exasol/sql/ValueTableRow.java
index 1c6b3887..e0e983f0 100644
--- a/src/main/java/com/exasol/sql/ValueTableRow.java
+++ b/src/main/java/com/exasol/sql/ValueTableRow.java
@@ -1,8 +1,11 @@
package com.exasol.sql;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
-import com.exasol.sql.expression.*;
+import com.exasol.sql.expression.ValueExpression;
+import com.exasol.sql.expression.literal.*;
/**
* This class represents a row in a {@link ValueTable}.
@@ -14,7 +17,7 @@ public class ValueTableRow extends AbstractFragment {
/**
* Create a value table row from a list of expressions.
*
- * @param root root node of the SQL statement
+ * @param root root node of the SQL statement
* @param expressions value expressions
*/
public ValueTableRow(final Fragment root, final ValueExpression... expressions) {
@@ -25,7 +28,7 @@ public ValueTableRow(final Fragment root, final ValueExpression... expressions)
/**
* Create a value table row from a list of string literals.
*
- * @param root root node of the SQL statement
+ * @param root root node of the SQL statement
* @param values sting literals
*/
public ValueTableRow(final Fragment root, final String... values) {
diff --git a/src/main/java/com/exasol/sql/dml/merge/MergeUpdateClause.java b/src/main/java/com/exasol/sql/dml/merge/MergeUpdateClause.java
index e7c45ff5..f2aab782 100644
--- a/src/main/java/com/exasol/sql/dml/merge/MergeUpdateClause.java
+++ b/src/main/java/com/exasol/sql/dml/merge/MergeUpdateClause.java
@@ -4,7 +4,9 @@
import java.util.List;
import com.exasol.sql.Fragment;
-import com.exasol.sql.expression.*;
+import com.exasol.sql.expression.DefaultValue;
+import com.exasol.sql.expression.ValueExpression;
+import com.exasol.sql.expression.literal.*;
/**
* Represents the {@code MERGE} strategy of updating matched rows.
@@ -24,7 +26,7 @@ public MergeUpdateClause(final Fragment root) {
/**
* Update a column with a value expression.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param expression value expression
* @return {@code this} for fluent programming
*/
@@ -36,7 +38,7 @@ public MergeUpdateClause set(final String column, final ValueExpression expressi
/**
* Update a column with a string value.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param literal string literal
* @return {@code this} for fluent programming
*/
@@ -47,7 +49,7 @@ public MergeUpdateClause set(final String column, final String literal) {
/**
* Update a column with a char value.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param literal char literal
* @return {@code this} for fluent programming
*/
@@ -58,7 +60,7 @@ public MergeUpdateClause set(final String column, final char literal) {
/**
* Update a column with an integer value.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param literal integer literal
* @return {@code this} for fluent programming
*/
@@ -69,7 +71,7 @@ public MergeUpdateClause set(final String column, final int literal) {
/**
* Update a column with a long value.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param literal long literal
* @return {@code this} for fluent programming
*/
@@ -80,7 +82,7 @@ public MergeUpdateClause set(final String column, final long literal) {
/**
* Update a column with a double value.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param literal double literal
* @return {@code this} for fluent programming
*/
@@ -91,7 +93,7 @@ public MergeUpdateClause set(final String column, final double literal) {
/**
* Update a column with a float value.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param literal float literal
* @return {@code this} for fluent programming
*/
@@ -102,7 +104,7 @@ public MergeUpdateClause set(final String column, final float literal) {
/**
* Update a column with a boolean value.
*
- * @param column column to be updated
+ * @param column column to be updated
* @param literal boolean literal
* @return {@code this} for fluent programming
*/
diff --git a/src/main/java/com/exasol/sql/dml/merge/rendering/MergeRenderer.java b/src/main/java/com/exasol/sql/dml/merge/rendering/MergeRenderer.java
index ae8593a4..bb559136 100644
--- a/src/main/java/com/exasol/sql/dml/merge/rendering/MergeRenderer.java
+++ b/src/main/java/com/exasol/sql/dml/merge/rendering/MergeRenderer.java
@@ -1,6 +1,9 @@
package com.exasol.sql.dml.merge.rendering;
-import com.exasol.sql.*;
+import com.exasol.sql.DerivedColumn;
+import com.exasol.sql.Table;
+import com.exasol.sql.ValueTable;
+import com.exasol.sql.ValueTableRow;
import com.exasol.sql.dml.insert.InsertFields;
import com.exasol.sql.dml.insert.rendering.InsertRenderer;
import com.exasol.sql.dml.merge.*;
@@ -47,7 +50,7 @@ public void visit(final UsingClause using) {
@Override
public void visit(final OnClause onClause) {
appendKeyWord(" ON ");
- appendRenderedBooleanExpression(onClause.getCondition());
+ appendRenderedValueExpression(onClause.getCondition());
setLastVisited(onClause);
}
@@ -155,7 +158,7 @@ public void leave(final ValueTableRow valueTableRow) {
@Override
public void visit(final WhereClause whereClause) {
appendKeyWord(" WHERE ");
- appendRenderedBooleanExpression(whereClause.getExpression());
+ appendRenderedValueExpression(whereClause.getExpression());
setLastVisited(whereClause);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/dql/select/rendering/SelectRenderer.java b/src/main/java/com/exasol/sql/dql/select/rendering/SelectRenderer.java
index 54ca7f68..474e7353 100644
--- a/src/main/java/com/exasol/sql/dql/select/rendering/SelectRenderer.java
+++ b/src/main/java/com/exasol/sql/dql/select/rendering/SelectRenderer.java
@@ -2,7 +2,10 @@
import java.util.List;
-import com.exasol.sql.*;
+import com.exasol.sql.DerivedColumn;
+import com.exasol.sql.Table;
+import com.exasol.sql.ValueTable;
+import com.exasol.sql.ValueTableRow;
import com.exasol.sql.dql.select.*;
import com.exasol.sql.expression.BooleanExpression;
import com.exasol.sql.rendering.AbstractFragmentRenderer;
@@ -84,7 +87,7 @@ public void visit(final Join join) {
@Override
public void visit(final WhereClause whereClause) {
appendKeyWord(" WHERE ");
- appendRenderedBooleanExpression(whereClause.getExpression());
+ appendRenderedValueExpression(whereClause.getExpression());
setLastVisited(whereClause);
}
@@ -95,7 +98,7 @@ public void visit(final GroupByClause groupByClause) {
final BooleanExpression having = groupByClause.getHavingBooleanExpression();
if (having != null) {
appendKeyWord(" HAVING ");
- appendRenderedBooleanExpression(having);
+ appendRenderedValueExpression(having);
}
setLastVisited(groupByClause);
}
diff --git a/src/main/java/com/exasol/sql/expression/AbstractBooleanExpression.java b/src/main/java/com/exasol/sql/expression/AbstractBooleanExpression.java
index d78fbe18..cb135788 100644
--- a/src/main/java/com/exasol/sql/expression/AbstractBooleanExpression.java
+++ b/src/main/java/com/exasol/sql/expression/AbstractBooleanExpression.java
@@ -1,46 +1,9 @@
package com.exasol.sql.expression;
-import com.exasol.util.AbstractBottomUpTreeNode;
-import com.exasol.util.TreeNode;
-
/**
* Abstract base class for all types of BooleanExpressions.
*/
-public abstract class AbstractBooleanExpression extends AbstractBottomUpTreeNode implements BooleanExpression {
- protected AbstractBooleanExpression() {
- super();
- }
-
- protected AbstractBooleanExpression(final BooleanExpression expression) {
- super(expression);
- }
-
- protected AbstractBooleanExpression(final BooleanExpression... expressions) {
- super(expressions);
- }
-
- @Override
- public void accept(final BooleanExpressionVisitor visitor) {
- acceptConcrete(visitor);
- for (final TreeNode child : this.getChildren()) {
- ((BooleanExpression) child).accept(visitor);
- }
- dismissConcrete(visitor);
- }
-
- /**
- * Sub-classes must override this method so that the visitor knows the type of the visited class at compile time.
- *
- * @param visitor visitor to accept
- */
- public abstract void acceptConcrete(final BooleanExpressionVisitor visitor);
-
- /**
- * Sub-classes must override this method so that the visitor knows the type of the visited class at compile time.
- *
- * @param visitor visitor to accept
- */
- public abstract void dismissConcrete(final BooleanExpressionVisitor visitor);
+public abstract class AbstractBooleanExpression implements BooleanExpression {
@Override
public void accept(final ValueExpressionVisitor visitor) {
diff --git a/src/main/java/com/exasol/sql/expression/AbstractValueExpression.java b/src/main/java/com/exasol/sql/expression/AbstractValueExpression.java
deleted file mode 100644
index fcf1f26f..00000000
--- a/src/main/java/com/exasol/sql/expression/AbstractValueExpression.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.exasol.sql.expression;
-
-import com.exasol.util.AbstractBottomUpTreeNode;
-
-/**
- * Abstract base class for all types of value expressions
- */
-public abstract class AbstractValueExpression extends AbstractBottomUpTreeNode implements ValueExpression {
- /**
- * Create a new instance of a {@link AbstractValueExpression}
- */
- public AbstractValueExpression() {
- super();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/And.java b/src/main/java/com/exasol/sql/expression/And.java
index 5b550a52..71207200 100644
--- a/src/main/java/com/exasol/sql/expression/And.java
+++ b/src/main/java/com/exasol/sql/expression/And.java
@@ -1,16 +1,23 @@
package com.exasol.sql.expression;
+import java.util.Arrays;
+import java.util.List;
+
+import com.exasol.sql.expression.literal.BooleanLiteral;
+
/**
* This class represents a logical AND predicate.
*/
public class And extends AbstractBooleanExpression {
+ private final List operands;
+
/**
* Create a new {@link And} instance
*
- * @param expressions boolean expressions to be connected by a logical AND
+ * @param operands boolean expressions to be connected by a logical AND
*/
- public And(final BooleanExpression... expressions) {
- super(expressions);
+ public And(final BooleanExpression... operands) {
+ this.operands = Arrays.asList(operands);
}
/**
@@ -22,13 +29,17 @@ public And(final boolean... values) {
this(BooleanLiteral.toBooleanExpressions(values));
}
- @Override
- public void acceptConcrete(final BooleanExpressionVisitor visitor) {
- visitor.visit(this);
+ /**
+ * Get the operands of this AND.
+ *
+ * @return operands of this AND
+ */
+ public List getOperands() {
+ return this.operands;
}
@Override
- public void dismissConcrete(final BooleanExpressionVisitor visitor) {
- visitor.leave(this);
+ public void accept(final BooleanExpressionVisitor visitor) {
+ visitor.visit(this);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/exasol/sql/expression/BinaryArithmeticExpression.java b/src/main/java/com/exasol/sql/expression/BinaryArithmeticExpression.java
index 82f0c68f..49c7cef1 100644
--- a/src/main/java/com/exasol/sql/expression/BinaryArithmeticExpression.java
+++ b/src/main/java/com/exasol/sql/expression/BinaryArithmeticExpression.java
@@ -1,14 +1,12 @@
package com.exasol.sql.expression;
-import com.exasol.util.AbstractTreeNode;
-
/**
* This class represents a binary arithmetic expression.
*
* Examples: +, -, *, /
*
*/
-public class BinaryArithmeticExpression extends AbstractTreeNode implements ValueExpression {
+public class BinaryArithmeticExpression implements ValueExpression {
private final BinaryArithmeticOperator arithmeticOperator;
private final ValueExpression left;
private final ValueExpression right;
@@ -18,16 +16,14 @@ private BinaryArithmeticExpression(final BinaryArithmeticOperator arithmeticOper
this.arithmeticOperator = arithmeticOperator;
this.left = left;
this.right = right;
- addChild(left);
- addChild(right);
}
/**
* Create a new {@link BinaryArithmeticExpression} instance.
*
* @param operator arithmetic operator represented by {@link BinaryArithmeticOperator}
- * @param left left part of the expression
- * @param right right part of the expression
+ * @param left left part of the expression
+ * @param right right part of the expression
* @return new {@link BinaryArithmeticExpression} instance
*/
public static BinaryArithmeticExpression of(final BinaryArithmeticOperator operator, final ValueExpression left,
diff --git a/src/main/java/com/exasol/sql/expression/BooleanExpressionVisitor.java b/src/main/java/com/exasol/sql/expression/BooleanExpressionVisitor.java
index 6251809f..f04889d9 100644
--- a/src/main/java/com/exasol/sql/expression/BooleanExpressionVisitor.java
+++ b/src/main/java/com/exasol/sql/expression/BooleanExpressionVisitor.java
@@ -1,6 +1,7 @@
package com.exasol.sql.expression;
import com.exasol.sql.expression.comparison.Comparison;
+import com.exasol.sql.expression.literal.BooleanLiteral;
/**
* Visitor interface for a {@link BooleanTerm}
@@ -12,13 +13,7 @@ public interface BooleanExpressionVisitor {
public void visit(And and);
- public void leave(Not not);
-
- public void leave(And and);
-
public void visit(Or or);
- public void leave(Or or);
-
public void visit(Comparison comparison);
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/BooleanTerm.java b/src/main/java/com/exasol/sql/expression/BooleanTerm.java
index b401cb08..583fcacf 100644
--- a/src/main/java/com/exasol/sql/expression/BooleanTerm.java
+++ b/src/main/java/com/exasol/sql/expression/BooleanTerm.java
@@ -3,6 +3,7 @@
import com.exasol.sql.expression.comparison.LikeComparison;
import com.exasol.sql.expression.comparison.SimpleComparison;
import com.exasol.sql.expression.comparison.SimpleComparisonOperator;
+import com.exasol.sql.expression.literal.BooleanLiteral;
// [impl->dsn~boolean-operators~1]
public abstract class BooleanTerm extends AbstractBooleanExpression {
diff --git a/src/main/java/com/exasol/sql/expression/ColumnReference.java b/src/main/java/com/exasol/sql/expression/ColumnReference.java
index fe24a0cd..feac3dfa 100644
--- a/src/main/java/com/exasol/sql/expression/ColumnReference.java
+++ b/src/main/java/com/exasol/sql/expression/ColumnReference.java
@@ -3,7 +3,7 @@
/**
* This class represents column reference.
*/
-public final class ColumnReference extends AbstractValueExpression {
+public final class ColumnReference implements ValueExpression {
private final String columnName;
private final String tableName;
@@ -15,7 +15,7 @@ private ColumnReference(final String columnName, final String tableName) {
/**
* Create a new {@link ColumnReference} from a column name and a table name.
*
- * @param tableName table name
+ * @param tableName table name
* @param columnName column name
*
* @return new {@link ColumnReference}
@@ -40,7 +40,7 @@ public static ColumnReference of(final String columnName) {
* @return column name
*/
public String getColumnName() {
- return columnName;
+ return this.columnName;
}
/**
@@ -49,16 +49,16 @@ public String getColumnName() {
* @return table name
*/
public String getTableName() {
- return tableName;
+ return this.tableName;
}
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
- if ((tableName != null) && !tableName.isEmpty()) {
- stringBuilder.append(tableName);
+ if ((this.tableName != null) && !this.tableName.isEmpty()) {
+ stringBuilder.append(this.tableName);
stringBuilder.append(".");
}
- stringBuilder.append(columnName);
+ stringBuilder.append(this.columnName);
return stringBuilder.toString();
}
diff --git a/src/main/java/com/exasol/sql/expression/DefaultValue.java b/src/main/java/com/exasol/sql/expression/DefaultValue.java
index c941c6d6..07f1dff9 100644
--- a/src/main/java/com/exasol/sql/expression/DefaultValue.java
+++ b/src/main/java/com/exasol/sql/expression/DefaultValue.java
@@ -8,7 +8,7 @@
*
*/
// [impl->dsn~literal-values~2]
-public final class DefaultValue extends AbstractValueExpression {
+public final class DefaultValue implements ValueExpression {
private static final DefaultValue instance = new DefaultValue();
public static ValueExpression defaultValue() {
diff --git a/src/main/java/com/exasol/sql/expression/ExpressionTerm.java b/src/main/java/com/exasol/sql/expression/ExpressionTerm.java
index 2f570bd3..fbad880e 100644
--- a/src/main/java/com/exasol/sql/expression/ExpressionTerm.java
+++ b/src/main/java/com/exasol/sql/expression/ExpressionTerm.java
@@ -5,13 +5,14 @@
import com.exasol.sql.expression.function.FunctionName;
import com.exasol.sql.expression.function.exasol.ExasolFunction;
import com.exasol.sql.expression.function.exasol.ExasolUdf;
+import com.exasol.sql.expression.literal.*;
/**
* Static factory methods for SQL expressions.
*/
-public abstract class ExpressionTerm extends AbstractValueExpression {
+public class ExpressionTerm {
private ExpressionTerm() {
- super();
+ // constructor hidden on purpose
}
/**
@@ -97,7 +98,7 @@ public static ColumnReference column(final String column) {
/**
* Create a reference to a column in a specific table.
*
- * @param table table name
+ * @param table table name
* @param column column name
*
* @return column reference
@@ -109,7 +110,7 @@ public static ColumnReference column(final String table, final String column) {
/**
* Create a binary arithmetic expression with ADD operator.
*
- * @param left left operand
+ * @param left left operand
* @param right right operand
* @return binary arithmetic expression
*/
@@ -120,7 +121,7 @@ public static BinaryArithmeticExpression plus(final ValueExpression left, final
/**
* Create a binary arithmetic expression with SUBTRACT operator.
*
- * @param left left operand
+ * @param left left operand
* @param right right operand
* @return binary arithmetic expression
*/
@@ -131,7 +132,7 @@ public static BinaryArithmeticExpression minus(final ValueExpression left, final
/**
* Create a binary arithmetic expression with DIVIDE operator.
*
- * @param left left operand
+ * @param left left operand
* @param right right operand
* @return binary arithmetic expression
*/
@@ -142,7 +143,7 @@ public static BinaryArithmeticExpression multiply(final ValueExpression left, fi
/**
* Create a binary arithmetic expression with DIVIDE operator.
*
- * @param left left operand
+ * @param left left operand
* @param right right operand
* @return binary arithmetic expression
*/
@@ -163,7 +164,7 @@ public static Function function(final FunctionName functionName) {
/**
* Create an Exasol function.
*
- * @param functionName a name of function
+ * @param functionName a name of function
* @param valueExpressions zero or more value expressions
* @return this
instance for fluent programming
*/
@@ -174,9 +175,9 @@ public static Function function(final FunctionName functionName, final ValueExpr
/**
* Create a User Defined Function.
*
- * @param functionName a name of function
+ * @param functionName a name of function
* @param emitsColumnsDefinition column definitions for emits
- * @param valueExpressions zero or more value expressions
+ * @param valueExpressions zero or more value expressions
* @return UDF
*/
public static Function udf(final String functionName, final ColumnsDefinition emitsColumnsDefinition,
@@ -187,7 +188,7 @@ public static Function udf(final String functionName, final ColumnsDefinition em
/**
* Create a User Defined Function.
*
- * @param functionName a name of function
+ * @param functionName a name of function
* @param valueExpressions zero or more value expressions
* @return UDF
*/
@@ -203,4 +204,4 @@ public static Function udf(final String functionName, final ValueExpression... v
public static NullLiteral nullLiteral() {
return NullLiteral.nullLiteral();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/exasol/sql/expression/Not.java b/src/main/java/com/exasol/sql/expression/Not.java
index c52e9752..f63fa5a2 100644
--- a/src/main/java/com/exasol/sql/expression/Not.java
+++ b/src/main/java/com/exasol/sql/expression/Not.java
@@ -1,16 +1,20 @@
package com.exasol.sql.expression;
+import com.exasol.sql.expression.literal.BooleanLiteral;
+
/**
* This class implements the logical unary NOT predicate.
*/
public class Not extends AbstractBooleanExpression {
+ private final BooleanExpression operand;
+
/**
* Create a new instance of a unary {@link Not} from a boolean literal
*
* @param value boolean literal to be negated
*/
public Not(final boolean value) {
- super(BooleanLiteral.of(value));
+ this(BooleanLiteral.of(value));
}
/**
@@ -19,25 +23,29 @@ public Not(final boolean value) {
* @param value string literal to be negated
*/
public Not(final String value) {
- super(BooleanLiteral.of(value));
+ this(BooleanLiteral.of(value));
}
/**
* Create a new instance of a unary {@link Not} from a boolean expression
*
- * @param expression boolean expression literal to be negated
+ * @param operand boolean expression literal to be negated
*/
- public Not(final BooleanExpression expression) {
- super(expression);
+ public Not(final BooleanExpression operand) {
+ this.operand = operand;
}
- @Override
- public void acceptConcrete(final BooleanExpressionVisitor visitor) {
- visitor.visit(this);
+ /**
+ * Get the boolean expression literal to be negated.
+ *
+ * @return boolean expression literal to be negated
+ */
+ public BooleanExpression getOperand() {
+ return this.operand;
}
@Override
- public void dismissConcrete(final BooleanExpressionVisitor visitor) {
- visitor.leave(this);
+ public void accept(final BooleanExpressionVisitor visitor) {
+ visitor.visit(this);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/Or.java b/src/main/java/com/exasol/sql/expression/Or.java
index 193028c6..5bc53732 100644
--- a/src/main/java/com/exasol/sql/expression/Or.java
+++ b/src/main/java/com/exasol/sql/expression/Or.java
@@ -1,16 +1,23 @@
package com.exasol.sql.expression;
+import java.util.Arrays;
+import java.util.List;
+
+import com.exasol.sql.expression.literal.BooleanLiteral;
+
/**
* This class represents a logical OR predicate.
*/
public class Or extends AbstractBooleanExpression {
+ private final List operands;
+
/**
* Create a new {@link Or} instance
*
- * @param expressions boolean expressions to be connected by a logical Or
+ * @param operands boolean expressions to be connected by a logical Or
*/
- public Or(final BooleanExpression... expressions) {
- super(expressions);
+ public Or(final BooleanExpression... operands) {
+ this.operands = Arrays.asList(operands);
}
/**
@@ -22,13 +29,17 @@ public Or(final boolean... values) {
this(BooleanLiteral.toBooleanExpressions(values));
}
- @Override
- public void acceptConcrete(final BooleanExpressionVisitor visitor) {
- visitor.visit(this);
+ /**
+ * Get the operands of this OR.
+ *
+ * @return operands of this OR
+ */
+ public List getOperands() {
+ return this.operands;
}
@Override
- public void dismissConcrete(final BooleanExpressionVisitor visitor) {
- visitor.leave(this);
+ public void accept(final BooleanExpressionVisitor visitor) {
+ visitor.visit(this);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/ValueExpression.java b/src/main/java/com/exasol/sql/expression/ValueExpression.java
index f01fa1da..8b614237 100644
--- a/src/main/java/com/exasol/sql/expression/ValueExpression.java
+++ b/src/main/java/com/exasol/sql/expression/ValueExpression.java
@@ -1,11 +1,9 @@
package com.exasol.sql.expression;
-import com.exasol.util.TreeNode;
-
/**
* Common interface for all types of value expressions
*/
-public interface ValueExpression extends TreeNode {
+public interface ValueExpression {
/**
* Accept a visitor
*
diff --git a/src/main/java/com/exasol/sql/expression/ValueExpressionVisitor.java b/src/main/java/com/exasol/sql/expression/ValueExpressionVisitor.java
index 716fecbe..35fb845f 100644
--- a/src/main/java/com/exasol/sql/expression/ValueExpressionVisitor.java
+++ b/src/main/java/com/exasol/sql/expression/ValueExpressionVisitor.java
@@ -1,47 +1,25 @@
package com.exasol.sql.expression;
import com.exasol.sql.UnnamedPlaceholder;
-import com.exasol.sql.expression.function.exasol.CastExasolFunction;
-import com.exasol.sql.expression.function.exasol.ExasolFunction;
-import com.exasol.sql.expression.function.exasol.ExasolUdf;
+import com.exasol.sql.expression.function.Function;
+import com.exasol.sql.expression.literal.Literal;
/**
* Visitor interface for a {@link BooleanTerm}.
*/
public interface ValueExpressionVisitor {
- public void visit(UnnamedPlaceholder unnamedPlaceholder);
-
- public void visit(StringLiteral literal);
-
- public void visit(IntegerLiteral literal);
-
- public void visit(LongLiteral literal);
-
- public void visit(DoubleLiteral literal);
-
- public void visit(FloatLiteral literal);
+ public void visit(final Literal literal);
- public void visit(BigDecimalLiteral literal);
+ public void visit(final Function function);
- public void visit(BooleanLiteral literal);
+ public void visit(UnnamedPlaceholder unnamedPlaceholder);
public void visit(ColumnReference columnReference);
public void visit(DefaultValue defaultValue);
- public void visit(ExasolFunction function);
-
- public void leave(ExasolFunction function);
-
- public void visit(ExasolUdf function);
-
- public void leave(ExasolUdf function);
-
public void visit(BinaryArithmeticExpression expression);
- public void visit(NullLiteral nullLiteral);
-
public void visit(BooleanExpression booleanExpression);
- public void visit(CastExasolFunction castFunction);
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/comparison/AbstractComparison.java b/src/main/java/com/exasol/sql/expression/comparison/AbstractComparison.java
index a63a97ce..e37370a5 100644
--- a/src/main/java/com/exasol/sql/expression/comparison/AbstractComparison.java
+++ b/src/main/java/com/exasol/sql/expression/comparison/AbstractComparison.java
@@ -26,16 +26,6 @@ protected AbstractComparison(final ComparisonOperator comparisonOperator, final
this.rightOperand = rightOperand;
}
- @Override
- public final void acceptConcrete(final BooleanExpressionVisitor visitor) {
- visitor.visit(this);
- }
-
- @Override
- public final void dismissConcrete(final BooleanExpressionVisitor visitor) {
- // empty on purpose
- }
-
/**
* Get the left-hand side operator of the comparison
*
@@ -65,4 +55,9 @@ public ValueExpression getRightOperand() {
public ComparisonOperator getOperator() {
return this.operator;
}
+
+ @Override
+ public void accept(final BooleanExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
}
diff --git a/src/main/java/com/exasol/sql/expression/function/AbstractFunction.java b/src/main/java/com/exasol/sql/expression/function/AbstractFunction.java
index dd3fb9bf..1ff44e12 100644
--- a/src/main/java/com/exasol/sql/expression/function/AbstractFunction.java
+++ b/src/main/java/com/exasol/sql/expression/function/AbstractFunction.java
@@ -3,32 +3,42 @@
import java.util.List;
import com.exasol.sql.expression.ValueExpression;
-import com.exasol.util.AbstractTreeNode;
+import com.exasol.sql.expression.ValueExpressionVisitor;
/**
* This is a base class for functions.
*/
-public abstract class AbstractFunction extends AbstractTreeNode implements Function {
+public abstract class AbstractFunction implements Function {
protected String functionName;
- protected List valueExpressions;
+ protected List parameters;
/**
* Create a new instance using {@link AbstractFunction}.
*
* @param functionName name of a function
- * @param valueExpressions zero or more value expressions
+ * @param parameters zero or more value expressions
*/
- protected AbstractFunction(final String functionName, final List valueExpressions) {
+ protected AbstractFunction(final String functionName, final List parameters) {
this.functionName = functionName;
- this.valueExpressions = valueExpressions;
- for (final ValueExpression valueExpression : this.valueExpressions) {
- addChild(valueExpression);
- valueExpression.setParent(this);
- }
+ this.parameters = parameters;
}
@Override
public String getFunctionName() {
return this.functionName;
}
+
+ /**
+ * Get the value expressions (parameters of the function)
+ *
+ * @return list of value expressions
+ */
+ public List getParameters() {
+ return this.parameters;
+ }
+
+ @Override
+ public final void accept(final ValueExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/function/Function.java b/src/main/java/com/exasol/sql/expression/function/Function.java
index e3eba8c3..47d34d02 100644
--- a/src/main/java/com/exasol/sql/expression/function/Function.java
+++ b/src/main/java/com/exasol/sql/expression/function/Function.java
@@ -18,5 +18,12 @@ public interface Function extends ValueExpression {
*
* @return true if function has parenthesis with parameters
*/
- boolean hasParenthesis();
+ public boolean hasParenthesis();
+
+ /**
+ * Accept {@link FunctionVisitor}.
+ *
+ * @param visitor visitor to accept
+ */
+ public void accept(final FunctionVisitor visitor);
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/function/FunctionVisitor.java b/src/main/java/com/exasol/sql/expression/function/FunctionVisitor.java
new file mode 100644
index 00000000..77fb0dcf
--- /dev/null
+++ b/src/main/java/com/exasol/sql/expression/function/FunctionVisitor.java
@@ -0,0 +1,16 @@
+package com.exasol.sql.expression.function;
+
+import com.exasol.sql.expression.function.exasol.CastExasolFunction;
+import com.exasol.sql.expression.function.exasol.ExasolFunction;
+import com.exasol.sql.expression.function.exasol.ExasolUdf;
+
+/**
+ * Visitor interface for {@link Function}.
+ */
+public interface FunctionVisitor {
+ public void visit(ExasolFunction function);
+
+ public void visit(ExasolUdf function);
+
+ public void visit(CastExasolFunction castFunction);
+}
diff --git a/src/main/java/com/exasol/sql/expression/function/exasol/CastExasolFunction.java b/src/main/java/com/exasol/sql/expression/function/exasol/CastExasolFunction.java
index c6158ad3..c0af3fdc 100644
--- a/src/main/java/com/exasol/sql/expression/function/exasol/CastExasolFunction.java
+++ b/src/main/java/com/exasol/sql/expression/function/exasol/CastExasolFunction.java
@@ -4,17 +4,18 @@
import com.exasol.datatype.type.DataType;
import com.exasol.sql.expression.ValueExpression;
-import com.exasol.sql.expression.ValueExpressionVisitor;
+import com.exasol.sql.expression.function.AbstractFunction;
import com.exasol.sql.expression.function.FunctionName;
+import com.exasol.sql.expression.function.FunctionVisitor;
/**
* This class represents the Exasol CAST function.
*/
-public class CastExasolFunction extends ExasolFunction {
+public class CastExasolFunction extends AbstractFunction {
private final DataType type;
private CastExasolFunction(final ValueExpression value, final DataType type) {
- super(ExasolScalarFunctionCast.CAST, List.of(value));
+ super(ExasolScalarFunctionCast.CAST.toString(), List.of(value));
this.type = type;
}
@@ -35,7 +36,7 @@ public static CastExasolFunction of(final ValueExpression valueExpression, final
* @return value to cast
*/
public ValueExpression getValue() {
- return this.valueExpressions.get(0);
+ return this.parameters.get(0);
}
/**
@@ -53,7 +54,7 @@ public boolean hasParenthesis() {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final FunctionVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/exasol/sql/expression/function/exasol/ExasolFunction.java b/src/main/java/com/exasol/sql/expression/function/exasol/ExasolFunction.java
index af065b90..c0a0211a 100644
--- a/src/main/java/com/exasol/sql/expression/function/exasol/ExasolFunction.java
+++ b/src/main/java/com/exasol/sql/expression/function/exasol/ExasolFunction.java
@@ -5,9 +5,9 @@
import java.util.List;
import com.exasol.sql.expression.ValueExpression;
-import com.exasol.sql.expression.ValueExpressionVisitor;
import com.exasol.sql.expression.function.AbstractFunction;
import com.exasol.sql.expression.function.FunctionName;
+import com.exasol.sql.expression.function.FunctionVisitor;
/**
* This class represents a function in the Exasol database.
@@ -47,11 +47,7 @@ public boolean hasParenthesis() {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final FunctionVisitor visitor) {
visitor.visit(this);
- for (final ValueExpression valueExpression : this.valueExpressions) {
- valueExpression.accept(visitor);
- }
- visitor.leave(this);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/function/exasol/ExasolUdf.java b/src/main/java/com/exasol/sql/expression/function/exasol/ExasolUdf.java
index 20cbc3f0..4e43cd53 100644
--- a/src/main/java/com/exasol/sql/expression/function/exasol/ExasolUdf.java
+++ b/src/main/java/com/exasol/sql/expression/function/exasol/ExasolUdf.java
@@ -1,11 +1,13 @@
package com.exasol.sql.expression.function.exasol;
-import java.util.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
import com.exasol.sql.ColumnsDefinition;
import com.exasol.sql.expression.ValueExpression;
-import com.exasol.sql.expression.ValueExpressionVisitor;
import com.exasol.sql.expression.function.AbstractFunction;
+import com.exasol.sql.expression.function.FunctionVisitor;
/**
* This class represents a User Defined Function in the Exasol database.
@@ -22,9 +24,9 @@ private ExasolUdf(final String functionName, final Optional e
/**
* Create a new {@link ExasolUdf} instance.
*
- * @param functionName name of the function
+ * @param functionName name of the function
* @param emitsColumnsDefinition column definitions for emits
- * @param valueExpressions zero or more value expressions
+ * @param valueExpressions zero or more value expressions
* @return new {@link ExasolUdf}
*/
public static ExasolUdf of(final String functionName, final ColumnsDefinition emitsColumnsDefinition,
@@ -35,7 +37,7 @@ public static ExasolUdf of(final String functionName, final ColumnsDefinition em
/**
* Create a new {@link ExasolUdf} instance.
*
- * @param functionName name of the function
+ * @param functionName name of the function
* @param valueExpressions zero or more value expressions
* @return new {@link ExasolUdf}
*/
@@ -48,6 +50,11 @@ public boolean hasParenthesis() {
return true;
}
+ @Override
+ public void accept(final FunctionVisitor visitor) {
+ visitor.visit(this);
+ }
+
/**
* Check if the EMITS part is required.
*
@@ -65,13 +72,4 @@ public boolean hasEmitsColumnsDefinition() {
public Optional getEmitsColumnsDefinition() {
return this.emitsColumnsDefinition;
}
-
- @Override
- public void accept(final ValueExpressionVisitor visitor) {
- visitor.visit(this);
- for (final ValueExpression valueExpression : this.valueExpressions) {
- valueExpression.accept(visitor);
- }
- visitor.leave(this);
- }
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/literal/AbstractLiteral.java b/src/main/java/com/exasol/sql/expression/literal/AbstractLiteral.java
new file mode 100644
index 00000000..c14a2ce1
--- /dev/null
+++ b/src/main/java/com/exasol/sql/expression/literal/AbstractLiteral.java
@@ -0,0 +1,14 @@
+package com.exasol.sql.expression.literal;
+
+import com.exasol.sql.expression.ValueExpression;
+import com.exasol.sql.expression.ValueExpressionVisitor;
+
+/**
+ * Abstract basis for {@link Literal}s.
+ */
+public abstract class AbstractLiteral implements Literal, ValueExpression {
+ @Override
+ public final void accept(final ValueExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+}
diff --git a/src/main/java/com/exasol/sql/expression/BigDecimalLiteral.java b/src/main/java/com/exasol/sql/expression/literal/BigDecimalLiteral.java
similarity index 65%
rename from src/main/java/com/exasol/sql/expression/BigDecimalLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/BigDecimalLiteral.java
index 0a258c48..178f1942 100644
--- a/src/main/java/com/exasol/sql/expression/BigDecimalLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/BigDecimalLiteral.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import java.math.BigDecimal;
@@ -6,10 +6,10 @@
* This class represents BigDecimal literals.
*/
// [impl->dsn~literal-values~2]
-public class BigDecimalLiteral extends AbstractValueExpression {
+public class BigDecimalLiteral extends AbstractLiteral {
private final BigDecimal literal;
- private BigDecimalLiteral(BigDecimal literal) {
+ private BigDecimalLiteral(final BigDecimal literal) {
this.literal = literal;
}
@@ -19,7 +19,7 @@ private BigDecimalLiteral(BigDecimal literal) {
* @param literal content
* @return new {@link StringLiteral}
*/
- public static BigDecimalLiteral of(BigDecimal literal) {
+ public static BigDecimalLiteral of(final BigDecimal literal) {
return new BigDecimalLiteral(literal);
}
@@ -29,16 +29,16 @@ public static BigDecimalLiteral of(BigDecimal literal) {
* @return BigDecimal value
*/
public BigDecimal getValue() {
- return literal;
+ return this.literal;
}
@Override
- public void accept(ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
visitor.visit(this);
}
@Override
public String toString() {
- return literal.toString();
+ return this.literal.toString();
}
}
diff --git a/src/main/java/com/exasol/sql/expression/BooleanLiteral.java b/src/main/java/com/exasol/sql/expression/literal/BooleanLiteral.java
similarity index 86%
rename from src/main/java/com/exasol/sql/expression/BooleanLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/BooleanLiteral.java
index 6ddde03c..2ff6a4ff 100644
--- a/src/main/java/com/exasol/sql/expression/BooleanLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/BooleanLiteral.java
@@ -1,10 +1,13 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
+
+import com.exasol.sql.expression.BooleanExpression;
+import com.exasol.sql.expression.BooleanExpressionVisitor;
/**
* This class represents boolean literals (read "true" and "false")
*/
// [impl->dsn~boolean-literals~1]
-public final class BooleanLiteral extends AbstractBooleanExpression implements ValueExpression {
+public final class BooleanLiteral extends AbstractLiteral implements BooleanExpression {
private static final String FALSE = "FALSE";
private static final String TRUE = "TRUE";
private final boolean value;
@@ -69,16 +72,6 @@ public boolean toBoolean() {
return this.value;
}
- @Override
- public void acceptConcrete(final BooleanExpressionVisitor visitor) {
- visitor.visit(this);
- }
-
- @Override
- public void dismissConcrete(final BooleanExpressionVisitor visitor) {
- // empty on purpose
- }
-
/**
* Map an array of booleans to and array of BooleanExpressions
*
@@ -94,7 +87,12 @@ public static BooleanExpression[] toBooleanExpressions(final boolean[] values) {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void accept(final BooleanExpressionVisitor visitor) {
visitor.visit(this);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/DoubleLiteral.java b/src/main/java/com/exasol/sql/expression/literal/DoubleLiteral.java
similarity index 82%
rename from src/main/java/com/exasol/sql/expression/DoubleLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/DoubleLiteral.java
index 3a879776..fb85969b 100644
--- a/src/main/java/com/exasol/sql/expression/DoubleLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/DoubleLiteral.java
@@ -1,10 +1,10 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
/**
* This class represents double literals.
*/
// [impl->dsn~literal-values~2]
-public class DoubleLiteral extends AbstractValueExpression {
+public class DoubleLiteral extends AbstractLiteral {
private final double value;
private DoubleLiteral(final double value) {
@@ -31,7 +31,7 @@ public double getValue() {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/exasol/sql/expression/FloatLiteral.java b/src/main/java/com/exasol/sql/expression/literal/FloatLiteral.java
similarity index 82%
rename from src/main/java/com/exasol/sql/expression/FloatLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/FloatLiteral.java
index 944b94de..2861d700 100644
--- a/src/main/java/com/exasol/sql/expression/FloatLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/FloatLiteral.java
@@ -1,10 +1,10 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
/**
* This class represents float literals.
*/
// [impl->dsn~literal-values~2]
-public class FloatLiteral extends AbstractValueExpression {
+public class FloatLiteral extends AbstractLiteral {
private final float value;
private FloatLiteral(final float value) {
@@ -31,7 +31,7 @@ public float getValue() {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/exasol/sql/expression/IntegerLiteral.java b/src/main/java/com/exasol/sql/expression/literal/IntegerLiteral.java
similarity index 82%
rename from src/main/java/com/exasol/sql/expression/IntegerLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/IntegerLiteral.java
index 28bf6c10..e1b169a6 100644
--- a/src/main/java/com/exasol/sql/expression/IntegerLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/IntegerLiteral.java
@@ -1,10 +1,10 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
/**
* This class represents integer literals.
*/
// [impl->dsn~literal-values~2]
-public final class IntegerLiteral extends AbstractValueExpression {
+public final class IntegerLiteral extends AbstractLiteral {
private final int value;
private IntegerLiteral(final int value) {
@@ -31,7 +31,7 @@ public int getValue() {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/exasol/sql/expression/literal/Literal.java b/src/main/java/com/exasol/sql/expression/literal/Literal.java
new file mode 100644
index 00000000..a4b78992
--- /dev/null
+++ b/src/main/java/com/exasol/sql/expression/literal/Literal.java
@@ -0,0 +1,15 @@
+package com.exasol.sql.expression.literal;
+
+import com.exasol.sql.expression.ValueExpression;
+
+/**
+ * Interface for classes that represent literal values.
+ */
+public interface Literal extends ValueExpression {
+ /**
+ * Accept a {@link LiteralVisitor}.
+ *
+ * @param visitor visitor to accept
+ */
+ public void accept(final LiteralVisitor visitor);
+}
diff --git a/src/main/java/com/exasol/sql/expression/literal/LiteralVisitor.java b/src/main/java/com/exasol/sql/expression/literal/LiteralVisitor.java
new file mode 100644
index 00000000..cfca8430
--- /dev/null
+++ b/src/main/java/com/exasol/sql/expression/literal/LiteralVisitor.java
@@ -0,0 +1,23 @@
+package com.exasol.sql.expression.literal;
+
+/**
+ * Visitor for {@link Literal}.
+ */
+public interface LiteralVisitor {
+ public void visit(final NullLiteral nullLiteral);
+
+ public void visit(final StringLiteral literal);
+
+ public void visit(final IntegerLiteral literal);
+
+ public void visit(final LongLiteral literal);
+
+ public void visit(final DoubleLiteral literal);
+
+ public void visit(final FloatLiteral literal);
+
+ public void visit(final BigDecimalLiteral literal);
+
+ public void visit(final BooleanLiteral literal);
+
+}
diff --git a/src/main/java/com/exasol/sql/expression/LongLiteral.java b/src/main/java/com/exasol/sql/expression/literal/LongLiteral.java
similarity index 82%
rename from src/main/java/com/exasol/sql/expression/LongLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/LongLiteral.java
index e2b18c7d..c7f3d07a 100644
--- a/src/main/java/com/exasol/sql/expression/LongLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/LongLiteral.java
@@ -1,10 +1,10 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
/**
* This class represents long literals.
*/
// [impl->dsn~literal-values~2]
-public class LongLiteral extends AbstractValueExpression {
+public class LongLiteral extends AbstractLiteral {
private final long value;
private LongLiteral(final long value) {
@@ -31,7 +31,7 @@ public long getValue() {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/exasol/sql/expression/NullLiteral.java b/src/main/java/com/exasol/sql/expression/literal/NullLiteral.java
similarity index 68%
rename from src/main/java/com/exasol/sql/expression/NullLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/NullLiteral.java
index 2e7bf1bb..8f8d038c 100644
--- a/src/main/java/com/exasol/sql/expression/NullLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/NullLiteral.java
@@ -1,10 +1,10 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
/**
* This class represents a null literal.
*/
// [impl->dsn~literal-values~2]
-public final class NullLiteral extends AbstractValueExpression {
+public final class NullLiteral extends AbstractLiteral {
private static final NullLiteral instance = new NullLiteral();
public static NullLiteral nullLiteral() {
@@ -16,7 +16,7 @@ private NullLiteral() {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
visitor.visit(this);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/StringLiteral.java b/src/main/java/com/exasol/sql/expression/literal/StringLiteral.java
similarity index 84%
rename from src/main/java/com/exasol/sql/expression/StringLiteral.java
rename to src/main/java/com/exasol/sql/expression/literal/StringLiteral.java
index e572cf14..74975b1f 100644
--- a/src/main/java/com/exasol/sql/expression/StringLiteral.java
+++ b/src/main/java/com/exasol/sql/expression/literal/StringLiteral.java
@@ -1,10 +1,10 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
/**
* This class represents string literals (or character literals in SQL terms).
*/
// [impl->dsn~literal-values~2]
-public final class StringLiteral extends AbstractValueExpression {
+public final class StringLiteral extends AbstractLiteral {
private final String literal;
private StringLiteral(final String literal) {
@@ -32,7 +32,7 @@ public static StringLiteral of(final char literal) {
}
@Override
- public void accept(final ValueExpressionVisitor visitor) {
+ public void accept(final LiteralVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/exasol/sql/expression/rendering/AbstractExpressionRenderer.java b/src/main/java/com/exasol/sql/expression/rendering/AbstractExpressionRenderer.java
index 5b628599..f782bce3 100644
--- a/src/main/java/com/exasol/sql/expression/rendering/AbstractExpressionRenderer.java
+++ b/src/main/java/com/exasol/sql/expression/rendering/AbstractExpressionRenderer.java
@@ -1,9 +1,6 @@
package com.exasol.sql.expression.rendering;
-import java.util.ArrayDeque;
-import java.util.Deque;
-
-import com.exasol.sql.expression.*;
+import com.exasol.sql.expression.literal.BooleanLiteral;
import com.exasol.sql.rendering.StringRendererConfig;
import com.exasol.util.QuotesApplier;
@@ -13,13 +10,10 @@
public abstract class AbstractExpressionRenderer {
protected final StringRendererConfig config;
protected final StringBuilder builder = new StringBuilder();
- protected final Deque connectorDeque = new ArrayDeque<>();
private final QuotesApplier quotesApplier;
- private ValueExpression lastVisited;
public AbstractExpressionRenderer(final StringRendererConfig config) {
this.config = config;
- this.lastVisited = null;
this.quotesApplier = new QuotesApplier(config);
}
@@ -27,18 +21,6 @@ protected void appendKeyword(final String keyword) {
this.builder.append(this.config.useLowerCase() ? keyword.toLowerCase() : keyword);
}
- protected void connect(final BooleanExpression expression) {
- if (expression.isChild() && !expression.isFirstSibling()) {
- appendConnector();
- }
- }
-
- private void appendConnector() {
- if (!this.connectorDeque.isEmpty()) {
- appendKeyword(this.connectorDeque.peek());
- }
- }
-
protected void appendBooleanLiteral(final BooleanLiteral literal) {
this.builder.append(this.config.useLowerCase() ? literal.toString().toLowerCase() : literal.toString());
}
@@ -60,18 +42,6 @@ protected void appendAutoQuoted(final String identifier) {
append(autoQuotedIdentifier);
}
- protected void appendCommaWhenNeeded(final ValueExpression valueExpression) {
- if ((this.lastVisited != null && !(valueExpression.getParent() instanceof BinaryArithmeticExpression))
- && (this.lastVisited.isSibling(valueExpression) || (valueExpression.getParent() != this.lastVisited
- && this.lastVisited.getClass().equals(valueExpression.getClass())))) {
- append(", ");
- }
- }
-
- protected void setLastVisited(final ValueExpression valueExpression) {
- this.lastVisited = valueExpression;
- }
-
/**
* Render expression to a string
*
diff --git a/src/main/java/com/exasol/sql/expression/rendering/BooleanExpressionRenderer.java b/src/main/java/com/exasol/sql/expression/rendering/BooleanExpressionRenderer.java
deleted file mode 100644
index 3a3f417c..00000000
--- a/src/main/java/com/exasol/sql/expression/rendering/BooleanExpressionRenderer.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.exasol.sql.expression.rendering;
-
-import com.exasol.sql.expression.*;
-import com.exasol.sql.expression.comparison.Comparison;
-import com.exasol.sql.rendering.StringRendererConfig;
-
-/**
- * Renderer for {@link BooleanExpression}s.
- */
-public class BooleanExpressionRenderer extends AbstractExpressionRenderer implements BooleanExpressionVisitor {
- public BooleanExpressionRenderer(final StringRendererConfig config) {
- super(config);
- }
-
- public BooleanExpressionRenderer() {
- this(StringRendererConfig.builder().build());
- }
-
- @Override
- public void visit(final Not not) {
- connect(not);
- appendKeyword("NOT");
- startParenthesis();
- }
-
- @Override
- public void leave(final Not not) {
- endParenthesis();
- }
-
- @Override
- public void visit(final And and) {
- connect(and);
- this.connectorDeque.push(" AND ");
- if (!and.isRoot()) {
- startParenthesis();
- }
- }
-
- @Override
- public void leave(final And and) {
- if (!and.isRoot()) {
- endParenthesis();
- }
- this.connectorDeque.pop();
- }
-
- @Override
- public void visit(final Or or) {
- connect(or);
- this.connectorDeque.push(" OR ");
- if (!or.isRoot()) {
- startParenthesis();
- }
- }
-
- @Override
- public void leave(final Or or) {
- if (!or.isRoot()) {
- endParenthesis();
- }
- this.connectorDeque.pop();
- }
-
- @Override
- public void visit(final BooleanLiteral literal) {
- connect(literal);
- appendBooleanLiteral(literal);
- }
-
- @Override
- public void visit(final Comparison comparison) {
- connect(comparison);
- final ComparisonRenderer comparisonRenderer = new ComparisonRenderer(this.config);
- comparison.accept(comparisonRenderer);
- append(comparisonRenderer.render());
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/sql/expression/rendering/ComparisonRenderer.java b/src/main/java/com/exasol/sql/expression/rendering/ComparisonRenderer.java
deleted file mode 100644
index 72a7dc2f..00000000
--- a/src/main/java/com/exasol/sql/expression/rendering/ComparisonRenderer.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.exasol.sql.expression.rendering;
-
-import com.exasol.sql.expression.ValueExpression;
-import com.exasol.sql.expression.comparison.Comparison;
-import com.exasol.sql.expression.comparison.ComparisonVisitor;
-import com.exasol.sql.expression.comparison.LikeComparison;
-import com.exasol.sql.expression.comparison.SimpleComparison;
-import com.exasol.sql.rendering.StringRendererConfig;
-
-/**
- * Renderer for {@link Comparison}s;
- */
-public class ComparisonRenderer extends AbstractExpressionRenderer implements ComparisonVisitor {
-
- /**
- * Create a new instance of {@link ComparisonRenderer}.
- *
- * @param config render configuration
- */
- public ComparisonRenderer(final StringRendererConfig config) {
- super(config);
- }
-
- @Override
- public void visit(final SimpleComparison simpleComparison) {
- openComparison(simpleComparison);
- closeComparison(simpleComparison);
- }
-
- @Override
- public void visit(final LikeComparison like) {
- openComparison(like);
- if (like.hasEscape()) {
- this.builder.append(" ESCAPE ");
- this.builder.append("'");
- this.builder.append(like.getEscape());
- this.builder.append("'");
- }
- closeComparison(like);
- }
-
- private void openComparison(final Comparison comparison) {
- connect(comparison);
- if (!comparison.isRoot()) {
- startParenthesis();
- }
- appendOperand(comparison.getLeftOperand());
- this.builder.append(" ");
- this.builder.append(comparison.getOperator().toString());
- this.builder.append(" ");
- appendOperand(comparison.getRightOperand());
- }
-
- private void closeComparison(final Comparison comparison) {
- if (!comparison.isRoot()) {
- endParenthesis();
- }
- }
-
- private void appendOperand(final ValueExpression leftOperand) {
- final ValueExpressionRenderer leftExpressionRenderer = new ValueExpressionRenderer(this.config);
- leftOperand.accept(leftExpressionRenderer);
- append(leftExpressionRenderer.render());
- }
-}
diff --git a/src/main/java/com/exasol/sql/expression/rendering/ValueExpressionRenderer.java b/src/main/java/com/exasol/sql/expression/rendering/ValueExpressionRenderer.java
index ee8d753c..4610001b 100644
--- a/src/main/java/com/exasol/sql/expression/rendering/ValueExpressionRenderer.java
+++ b/src/main/java/com/exasol/sql/expression/rendering/ValueExpressionRenderer.java
@@ -1,127 +1,239 @@
package com.exasol.sql.expression.rendering;
+import java.util.List;
+
import com.exasol.datatype.type.DataType;
import com.exasol.sql.ColumnsDefinition;
import com.exasol.sql.UnnamedPlaceholder;
import com.exasol.sql.expression.*;
+import com.exasol.sql.expression.comparison.Comparison;
+import com.exasol.sql.expression.comparison.ComparisonVisitor;
+import com.exasol.sql.expression.comparison.LikeComparison;
+import com.exasol.sql.expression.comparison.SimpleComparison;
+import com.exasol.sql.expression.function.AbstractFunction;
import com.exasol.sql.expression.function.Function;
+import com.exasol.sql.expression.function.FunctionVisitor;
import com.exasol.sql.expression.function.exasol.CastExasolFunction;
import com.exasol.sql.expression.function.exasol.ExasolFunction;
import com.exasol.sql.expression.function.exasol.ExasolUdf;
+import com.exasol.sql.expression.literal.*;
import com.exasol.sql.rendering.ColumnsDefinitionRenderer;
import com.exasol.sql.rendering.StringRendererConfig;
/**
* Renderer for common value expressions.
*/
-public class ValueExpressionRenderer extends AbstractExpressionRenderer implements ValueExpressionVisitor {
+public class ValueExpressionRenderer extends AbstractExpressionRenderer implements BooleanExpressionVisitor,
+ ComparisonVisitor, ValueExpressionVisitor, LiteralVisitor, FunctionVisitor {
+ int nestedLevel = 0;
+
+ /**
+ * Create a new instance of {@link ValueExpressionRenderer}.
+ *
+ * @param config render configuration
+ */
public ValueExpressionRenderer(final StringRendererConfig config) {
super(config);
}
@Override
- public void visit(final StringLiteral literal) {
- appendCommaWhenNeeded(literal);
- append("'");
- append(literal.toString());
- append("'");
- setLastVisited(literal);
+ public void visit(final Not not) {
+ appendKeyword("NOT");
+ startParenthesis();
+ not.getOperand().accept((BooleanExpressionVisitor) this);
+ endParenthesis();
}
@Override
- public void visit(final IntegerLiteral literal) {
- appendCommaWhenNeeded(literal);
- append(literal.toString());
- setLastVisited(literal);
+ public void visit(final And and) {
+ startParenthesisIfNested();
+ append(" AND ", and.getOperands());
+ endParenthesisIfNested();
+ }
+
+ private void append(final String separator, final List expressions) {
+ boolean isFirst = true;
+ for (final BooleanExpression expression : expressions) {
+ if (!isFirst) {
+ appendKeyword(separator);
+ }
+ isFirst = false;
+ expression.accept((BooleanExpressionVisitor) this);
+ }
}
@Override
- public void visit(final LongLiteral literal) {
- appendCommaWhenNeeded(literal);
- append(literal.toString());
- setLastVisited(literal);
+ public void visit(final Or or) {
+ startParenthesisIfNested();
+ append(" OR ", or.getOperands());
+ endParenthesisIfNested();
}
@Override
- public void visit(final DoubleLiteral literal) {
- appendCommaWhenNeeded(literal);
- append(literal.toString());
- setLastVisited(literal);
+ public void visit(final BooleanLiteral literal) {
+ appendBooleanLiteral(literal);
}
@Override
- public void visit(final FloatLiteral literal) {
- appendCommaWhenNeeded(literal);
- append(literal.toString());
- setLastVisited(literal);
+ public void visit(final Comparison comparison) {
+ comparison.accept((ComparisonVisitor) this);
}
+ /*
+ * Comparison renderer
+ */
@Override
- public void visit(final BigDecimalLiteral literal) {
- appendCommaWhenNeeded(literal);
- append(literal.toString());
- setLastVisited(literal);
+ public void visit(final SimpleComparison simpleComparison) {
+ openComparison(simpleComparison);
+ closeComparison();
}
@Override
- public void visit(final BooleanLiteral literal) {
- appendCommaWhenNeeded(literal);
- append(literal.toString());
- setLastVisited(literal);
+ public void visit(final LikeComparison like) {
+ openComparison(like);
+ if (like.hasEscape()) {
+ appendKeyword(" ESCAPE ");
+ append("'");
+ this.builder.append(like.getEscape());
+ append("'");
+ }
+ closeComparison();
+ }
+
+ private void openComparison(final Comparison comparison) {
+ startParenthesisIfNested();
+ appendOperand(comparison.getLeftOperand());
+ this.builder.append(" ");
+ this.builder.append(comparison.getOperator().toString());
+ this.builder.append(" ");
+
+ appendOperand(comparison.getRightOperand());
+ }
+
+ private void closeComparison() {
+ endParenthesisIfNested();
+ }
+
+ /* Value expression visitor */
+
+ public void visit(final ValueExpression... valueExpression) {
+ boolean isFirst = true;
+ for (final ValueExpression parameter : valueExpression) {
+ if (!isFirst) {
+ append(", ");
+ }
+ isFirst = false;
+ parameter.accept(this);
+ }
}
@Override
public void visit(final ColumnReference columnReference) {
- appendCommaWhenNeeded(columnReference);
appendAutoQuoted(columnReference.toString());
- setLastVisited(columnReference);
+ }
+
+ @Override
+ public void visit(final Literal literal) {
+ literal.accept((LiteralVisitor) this);
+ }
+
+ @Override
+ public void visit(final Function function) {
+ function.accept((FunctionVisitor) this);
+ }
+
+ @Override
+ public void visit(final BooleanExpression booleanExpression) {
+ booleanExpression.accept((BooleanExpressionVisitor) this);
}
@Override
public void visit(final UnnamedPlaceholder unnamedPlaceholder) {
append("?");
- setLastVisited(unnamedPlaceholder);
}
@Override
public void visit(final DefaultValue defaultValue) {
appendKeyword("DEFAULT");
- setLastVisited(defaultValue);
+ }
+
+ /** Literal visitor **/
+ @Override
+ public void visit(final StringLiteral literal) {
+ append("'");
+ append(literal.toString());
+ append("'");
+ }
+
+ @Override
+ public void visit(final IntegerLiteral literal) {
+ append(literal.toString());
+ }
+
+ @Override
+ public void visit(final LongLiteral literal) {
+ append(literal.toString());
+ }
+
+ @Override
+ public void visit(final DoubleLiteral literal) {
+ append(literal.toString());
+ }
+
+ @Override
+ public void visit(final FloatLiteral literal) {
+ append(literal.toString());
+ }
+
+ @Override
+ public void visit(final BigDecimalLiteral literal) {
+ append(literal.toString());
}
+ @Override
+ public void visit(final NullLiteral nullLiteral) {
+ appendKeyword("NULL");
+ }
+
+ /** Function visitor */
+
@Override
public void visit(final ExasolFunction function) {
- visitFunction(function);
+ renderFunction(function);
}
- private void visitFunction(final Function function) {
- appendCommaWhenNeeded(function);
+ private void renderFunction(final AbstractFunction function) {
appendKeyword(function.getFunctionName());
if (function.hasParenthesis()) {
startParenthesis();
}
- }
-
- @Override
- public void leave(final ExasolFunction function) {
+ ++this.nestedLevel;
+ this.visit(function.getParameters().toArray(ValueExpression[]::new));
+ --this.nestedLevel;
if (function.hasParenthesis()) {
endParenthesis();
}
- setLastVisited(function);
}
@Override
public void visit(final ExasolUdf function) {
- visitFunction(function);
+ renderFunction(function);
+ appendEmitsWhenNecessary(function);
}
@Override
- public void leave(final ExasolUdf function) {
- if (function.hasParenthesis()) {
- endParenthesis();
- }
- appendEmitsWhenNecessary(function);
- setLastVisited(function);
+ public void visit(final CastExasolFunction castFunction) {
+ appendKeyword("CAST");
+ startParenthesis();
+ ++this.nestedLevel;
+ castFunction.getValue().accept(this);
+ appendKeyword(" AS ");
+ final DataType type = castFunction.getType();
+ final ColumnsDefinitionRenderer columnsDefinitionRenderer = getColumnsDefinitionRenderer();
+ type.accept(columnsDefinitionRenderer);
+ append(columnsDefinitionRenderer.render());
+ --this.nestedLevel;
+ endParenthesis();
}
@SuppressWarnings("squid:S3655")
@@ -139,49 +251,34 @@ private void appendEmitsWhenNecessary(final ExasolUdf function) {
@Override
public void visit(final BinaryArithmeticExpression expression) {
- appendCommaWhenNeeded(expression);
startParenthesis();
+ ++this.nestedLevel;
appendOperand(expression.getLeft());
append(expression.getStringOperatorRepresentation());
appendOperand(expression.getRight());
+ --this.nestedLevel;
endParenthesis();
- setLastVisited(expression);
- }
-
- protected void appendOperand(final ValueExpression operand) {
- final ValueExpressionRenderer expressionRenderer = new ValueExpressionRenderer(this.config);
- operand.accept(expressionRenderer);
- this.builder.append(expressionRenderer.render());
}
- @Override
- public void visit(final NullLiteral nullLiteral) {
- appendCommaWhenNeeded(nullLiteral);
- appendKeyword("NULL");
- setLastVisited(nullLiteral);
+ private void appendOperand(final ValueExpression operand) {
+ operand.accept(this);
}
- @Override
- public void visit(final BooleanExpression booleanExpression) {
- final BooleanExpressionRenderer expressionRenderer = new BooleanExpressionRenderer(this.config);
- booleanExpression.accept(expressionRenderer);
- append(expressionRenderer.render());
+ private ColumnsDefinitionRenderer getColumnsDefinitionRenderer() {
+ return new ColumnsDefinitionRenderer(this.config);
}
- @Override
- public void visit(final CastExasolFunction castFunction) {
- appendKeyword("CAST");
- startParenthesis();
- castFunction.getValue().accept(this);
- appendKeyword(" AS");
- final DataType type = castFunction.getType();
- final ColumnsDefinitionRenderer columnsDefinitionRenderer = getColumnsDefinitionRenderer();
- type.accept(columnsDefinitionRenderer);
- append(columnsDefinitionRenderer.render());
- endParenthesis();
+ private void startParenthesisIfNested() {
+ if (this.nestedLevel > 0) {
+ startParenthesis();
+ }
+ ++this.nestedLevel;
}
- private ColumnsDefinitionRenderer getColumnsDefinitionRenderer() {
- return new ColumnsDefinitionRenderer(this.config);
+ private void endParenthesisIfNested() {
+ --this.nestedLevel;
+ if (this.nestedLevel > 0) {
+ endParenthesis();
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/exasol/sql/rendering/AbstractFragmentRenderer.java b/src/main/java/com/exasol/sql/rendering/AbstractFragmentRenderer.java
index 4c1fac6c..424ab921 100644
--- a/src/main/java/com/exasol/sql/rendering/AbstractFragmentRenderer.java
+++ b/src/main/java/com/exasol/sql/rendering/AbstractFragmentRenderer.java
@@ -4,9 +4,7 @@
import com.exasol.sql.Fragment;
import com.exasol.sql.ValueTableRow;
-import com.exasol.sql.expression.BooleanExpression;
import com.exasol.sql.expression.ValueExpression;
-import com.exasol.sql.expression.rendering.BooleanExpressionRenderer;
import com.exasol.sql.expression.rendering.ValueExpressionRenderer;
import com.exasol.util.QuotesApplier;
@@ -43,12 +41,16 @@ protected void endParenthesis() {
this.builder.append(")");
}
+ protected void appendRenderedValueExpression(final ValueExpression expression) {
+ final ValueExpressionRenderer renderer = new ValueExpressionRenderer(this.config);
+ expression.accept(renderer);
+ append(renderer.render());
+ }
+
protected void appendListOfValueExpressions(final List extends ValueExpression> valueExpressions) {
if ((valueExpressions != null) && !valueExpressions.isEmpty()) {
final ValueExpressionRenderer valueExpressionRenderer = new ValueExpressionRenderer(this.config);
- for (final ValueExpression valueExpression : valueExpressions) {
- valueExpression.accept(valueExpressionRenderer);
- }
+ valueExpressionRenderer.visit(valueExpressions.toArray(ValueExpression[]::new));
this.builder.append(valueExpressionRenderer.render());
}
}
@@ -71,22 +73,10 @@ protected void appendCommaWhenNeeded(final Fragment fragment) {
}
}
- protected void appendRenderedBooleanExpression(final BooleanExpression expression) {
- final BooleanExpressionRenderer expressionRenderer = new BooleanExpressionRenderer(this.config);
- expression.accept(expressionRenderer);
- append(expressionRenderer.render());
- }
-
protected void append(final int number) {
this.builder.append(number);
}
- protected void appendRenderedValueExpression(final ValueExpression expression) {
- final ValueExpressionRenderer renderer = new ValueExpressionRenderer(this.config);
- expression.accept(renderer);
- append(renderer.render());
- }
-
protected void appendAutoQuoted(final String identifier) {
final String autoQuotedIdentifier = this.quotesApplier.getAutoQuoted(identifier);
append(autoQuotedIdentifier);
diff --git a/src/main/java/com/exasol/util/AbstractBottomUpTreeNode.java b/src/main/java/com/exasol/util/AbstractBottomUpTreeNode.java
deleted file mode 100644
index 4806f966..00000000
--- a/src/main/java/com/exasol/util/AbstractBottomUpTreeNode.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.exasol.util;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * This is an abstract base class for nodes in a tree structure.
- */
-public abstract class AbstractBottomUpTreeNode extends AbstractTree {
- /**
- * Create a new instance of a {@link AbstractBottomUpTreeNode}.
- *
- * @param children child nodes to be linked to this node.
- */
- public AbstractBottomUpTreeNode(final List children) {
- this.children = children;
- for (final TreeNode child : children) {
- assignThisAsParentTo(child);
- }
- }
-
- /**
- * Create a new instance of a {@link AbstractBottomUpTreeNode}.
- *
- * @param children child nodes to be linked to this node.
- */
- public AbstractBottomUpTreeNode(final TreeNode... children) {
- this(Arrays.asList(children));
- }
-
- private void assignThisAsParentTo(final TreeNode child) {
- assertChildType(child);
- assertChildDoesNotAlreadyHaveAParent(child);
- ((AbstractBottomUpTreeNode) child).parent = this;
- }
-
- private void assertChildType(final TreeNode child) {
- if (!(child instanceof AbstractBottomUpTreeNode)) {
- throw new IllegalArgumentException("A bottom up tree can only be constructed from nodes of type \""
- + AbstractBottomUpTreeNode.class.getName() + "\" but got an object of type \""
- + child.getClass().getName() + "\"");
- }
- }
-
- private void assertChildDoesNotAlreadyHaveAParent(final TreeNode child) {
- if (child.getParent() != null) {
- throw new IllegalStateException(
- "Tried to link node \"" + child.toString() + "\" in bottom-up tree to parent \"" + this.toString()
- + "\" which already has a parent \"" + child.getParent() + "\"");
- }
- }
-
- @Override
- public TreeNode getRoot() {
- if (getParent() == null) {
- return this;
- } else {
- return getParent().getRoot();
- }
- }
-
- @Override
- public void addChild(final TreeNode child) {
- throw new UnsupportedOperationException("Node \"" + child.toString()
- + "\" can only be added as child node in parent constructor in a bottom-up tree.");
- }
-
- @Override
- public void setParent(final TreeNode parent) {
- this.parent = parent;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/util/AbstractTree.java b/src/main/java/com/exasol/util/AbstractTree.java
deleted file mode 100644
index 6a5f41fa..00000000
--- a/src/main/java/com/exasol/util/AbstractTree.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.exasol.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An abstract base for {@link TreeNode} implementations.
- */
-public abstract class AbstractTree implements TreeNode {
- protected TreeNode parent = null;
- protected List children = new ArrayList<>();
-
- @Override
- public TreeNode getParent() {
- return this.parent;
- }
-
- @Override
- public List getChildren() {
- return this.children;
- }
-
- @Override
- public TreeNode getChild(final int index) {
- return this.children.get(index);
- }
-
- @Override
- public boolean isRoot() {
- return (this == getRoot());
- }
-
- @Override
- public boolean isChild() {
- return (this.parent != null);
- }
-
- @Override
- public boolean isFirstSibling() {
- return (this.parent != null) && (this.getParent().getChild(0) == this);
- }
-
- @Override
- public boolean isSibling(final TreeNode node) {
- return (this.parent != null) && (this.getParent().getChildren().contains(node));
- }
-}
diff --git a/src/main/java/com/exasol/util/AbstractTreeNode.java b/src/main/java/com/exasol/util/AbstractTreeNode.java
deleted file mode 100644
index 070b8106..00000000
--- a/src/main/java/com/exasol/util/AbstractTreeNode.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.exasol.util;
-
-/**
- * This is an abstract base class for nodes in a tree structure.
- */
-public abstract class AbstractTreeNode extends AbstractTree {
- private TreeNode root;
-
- /**
- * Create a new instance of a {@link AbstractTreeNode} that serves as root for a tree.
- */
- public AbstractTreeNode() {
- this.root = this;
- this.parent = null;
- }
-
- /**
- * Link to a parent node
- *
- * @param parent the parent to which this node will be linked as a child
- *
- * @throws IllegalArgumentException if parent is null
or parent and child are identical
- */
- @Override
- public void setParent(final TreeNode parent) {
- if (parent == null) {
- throw new IllegalArgumentException("Parent tree node cannot be NULL.");
- } else if (parent == this) {
- throw new IllegalArgumentException("Parent tree node cannot be the same as child tree node.");
- } else {
- this.parent = parent;
- this.root = this.parent.getRoot();
- }
- }
-
- @Override
- public TreeNode getRoot() {
- return this.root;
- }
-
- @Override
- public void addChild(final TreeNode child) {
- this.children.add(child);
- child.setParent(this);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/exasol/util/TreeNode.java b/src/main/java/com/exasol/util/TreeNode.java
deleted file mode 100644
index 014d9eb8..00000000
--- a/src/main/java/com/exasol/util/TreeNode.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.exasol.util;
-
-import java.util.List;
-
-/**
- * This class represents a node in a tree structure.
- */
-public interface TreeNode {
- /**
- * Get the root of the tree
- *
- * @return root node
- */
- public TreeNode getRoot();
-
- /**
- * Get the parent of this node
- *
- * @return parent node
- */
- public TreeNode getParent();
-
- /**
- * Add a child node below this node. Children are registered in the order in which they are added.
- *
- * Important: this also automatically creates a link in the opposite direction. All implementations
- * must adhere to this rule.
- *
- * @param child child node
- */
- public void addChild(TreeNode child);
-
- /**
- * Get all child nodes of this node
- *
- * @return child nodes
- */
- public List getChildren();
-
- /**
- * Get child node by position in the list of siblings. The position depends on the order in which the children were
- * added.
- *
- * @param index position in the list of siblings
- * @return child node at position
- * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index ≥ size())
- */
- public TreeNode getChild(int index);
-
- /**
- * Check whether this node is the root of the tree.
- *
- * @return true
if this node is the root
- */
- public boolean isRoot();
-
- /**
- * Check whether this node is a child node
- *
- * @return true
if the node is a child of another node
- */
- public boolean isChild();
-
- /**
- * Check whether a child is the first in the list of siblings
- *
- * @return true
if the child is the first in the list of siblings
- */
- public boolean isFirstSibling();
-
- /**
- * Check whether this node is a sibling of the second node.
- *
- * @param node second node
- * @return true if two nodes are siblings
- */
- public boolean isSibling(TreeNode node);
-
- /**
- * Set a parent for this node.
- *
- * @param parent a node to set as a parent
- */
- public void setParent(TreeNode parent);
-}
\ No newline at end of file
diff --git a/src/test/java/com/exasol/hamcrest/BooleanExpressionRenderResultMatcher.java b/src/test/java/com/exasol/hamcrest/BooleanExpressionRenderResultMatcher.java
deleted file mode 100644
index 7bee09fd..00000000
--- a/src/test/java/com/exasol/hamcrest/BooleanExpressionRenderResultMatcher.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.exasol.hamcrest;
-
-import org.hamcrest.Description;
-
-import com.exasol.sql.dql.select.rendering.SelectRenderer;
-import com.exasol.sql.expression.BooleanExpression;
-import com.exasol.sql.expression.rendering.BooleanExpressionRenderer;
-import com.exasol.sql.rendering.StringRendererConfig;
-
-/**
- * This class implements a matcher for the results of rendering boolean expressions to text.
- */
-public class BooleanExpressionRenderResultMatcher extends AbstractRenderResultMatcher {
- private final BooleanExpressionRenderer renderer;
-
- private BooleanExpressionRenderResultMatcher(final String expectedText) {
- super(expectedText);
- this.renderer = new BooleanExpressionRenderer();
- }
-
- private BooleanExpressionRenderResultMatcher(final StringRendererConfig config, final String expectedText) {
- super(expectedText);
- this.renderer = new BooleanExpressionRenderer(config);
- }
-
- /**
- * Factory method for {@link BooleanExpressionRenderResultMatcher}
- *
- * @param expectedText text that represents the expected rendering result
- * @return the matcher
- */
- public static BooleanExpressionRenderResultMatcher rendersTo(final String expectedText) {
- return new BooleanExpressionRenderResultMatcher(expectedText);
- }
-
- /**
- * Factory method for {@link BooleanExpressionRenderResultMatcher}
- *
- * @param config configuration settings for the {@link SelectRenderer}
- * @param expectedText text that represents the expected rendering result
- * @return the matcher
- */
- public static BooleanExpressionRenderResultMatcher rendersWithConfigTo(final StringRendererConfig config,
- final String expectedText) {
- return new BooleanExpressionRenderResultMatcher(config, expectedText);
- }
-
- /**
- * Match the rendered result against original text.
- *
- * @param expression expression to be matched against the original text.
- */
- @Override
- public boolean matchesSafely(final BooleanExpression expression) {
- expression.accept(this.renderer);
- this.renderedText = this.renderer.render();
- return this.renderedText.equals(this.expectedText);
- }
-
- @Override
- protected void describeMismatchSafely(final BooleanExpression expression, final Description mismatchDescription) {
- mismatchDescription.appendText(this.renderedText);
- }
-}
\ No newline at end of file
diff --git a/src/test/java/com/exasol/hamcrest/ValueExpressionRenderResultMatcher.java b/src/test/java/com/exasol/hamcrest/ValueExpressionRenderResultMatcher.java
new file mode 100644
index 00000000..da8ea317
--- /dev/null
+++ b/src/test/java/com/exasol/hamcrest/ValueExpressionRenderResultMatcher.java
@@ -0,0 +1,64 @@
+package com.exasol.hamcrest;
+
+import org.hamcrest.Description;
+
+import com.exasol.sql.dql.select.rendering.SelectRenderer;
+import com.exasol.sql.expression.ValueExpression;
+import com.exasol.sql.expression.rendering.ValueExpressionRenderer;
+import com.exasol.sql.rendering.StringRendererConfig;
+
+/**
+ * This class implements a matcher for the results of rendering boolean expressions to text.
+ */
+public class ValueExpressionRenderResultMatcher extends AbstractRenderResultMatcher {
+ private final ValueExpressionRenderer renderer;
+
+ private ValueExpressionRenderResultMatcher(final String expectedText) {
+ super(expectedText);
+ this.renderer = new ValueExpressionRenderer(StringRendererConfig.createDefault());
+ }
+
+ private ValueExpressionRenderResultMatcher(final StringRendererConfig config, final String expectedText) {
+ super(expectedText);
+ this.renderer = new ValueExpressionRenderer(config);
+ }
+
+ /**
+ * Factory method for {@link ValueExpressionRenderResultMatcher}
+ *
+ * @param expectedText text that represents the expected rendering result
+ * @return the matcher
+ */
+ public static ValueExpressionRenderResultMatcher rendersTo(final String expectedText) {
+ return new ValueExpressionRenderResultMatcher(expectedText);
+ }
+
+ /**
+ * Factory method for {@link ValueExpressionRenderResultMatcher}
+ *
+ * @param config configuration settings for the {@link SelectRenderer}
+ * @param expectedText text that represents the expected rendering result
+ * @return the matcher
+ */
+ public static ValueExpressionRenderResultMatcher rendersWithConfigTo(final StringRendererConfig config,
+ final String expectedText) {
+ return new ValueExpressionRenderResultMatcher(config, expectedText);
+ }
+
+ /**
+ * Match the rendered result against original text.
+ *
+ * @param expression expression to be matched against the original text.
+ */
+ @Override
+ public boolean matchesSafely(final ValueExpression expression) {
+ expression.accept(this.renderer);
+ this.renderedText = this.renderer.render();
+ return this.renderedText.equals(this.expectedText);
+ }
+
+ @Override
+ protected void describeMismatchSafely(final ValueExpression expression, final Description mismatchDescription) {
+ mismatchDescription.appendText(this.renderedText);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/exasol/sql/dml/merge/MergeMethodDefinitionTest.java b/src/test/java/com/exasol/sql/dml/merge/MergeMethodDefinitionTest.java
index 0a3dd29c..f71568d0 100644
--- a/src/test/java/com/exasol/sql/dml/merge/MergeMethodDefinitionTest.java
+++ b/src/test/java/com/exasol/sql/dml/merge/MergeMethodDefinitionTest.java
@@ -11,7 +11,7 @@
import org.mockito.junit.jupiter.MockitoExtension;
import com.exasol.sql.Fragment;
-import com.exasol.sql.expression.BooleanLiteral;
+import com.exasol.sql.expression.literal.BooleanLiteral;
@ExtendWith(MockitoExtension.class)
class MergeMethodDefinitionTest {
diff --git a/src/test/java/com/exasol/sql/expression/TestComparisonOperator.java b/src/test/java/com/exasol/sql/expression/comparison/TestComparisonOperator.java
similarity index 88%
rename from src/test/java/com/exasol/sql/expression/TestComparisonOperator.java
rename to src/test/java/com/exasol/sql/expression/comparison/TestComparisonOperator.java
index d659c555..57ea01c6 100644
--- a/src/test/java/com/exasol/sql/expression/TestComparisonOperator.java
+++ b/src/test/java/com/exasol/sql/expression/comparison/TestComparisonOperator.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.comparison;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
@@ -6,8 +6,6 @@
import org.junit.jupiter.api.Test;
-import com.exasol.sql.expression.comparison.SimpleComparisonOperator;
-
class TestComparisonOperator {
@Test
void testToString() {
diff --git a/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java b/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java
index 7a1c167a..bfb34bca 100644
--- a/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java
+++ b/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java
@@ -8,20 +8,20 @@
import com.exasol.datatype.type.Varchar;
import com.exasol.sql.StatementFactory;
import com.exasol.sql.dql.select.Select;
-import com.exasol.sql.expression.NullLiteral;
+import com.exasol.sql.expression.literal.NullLiteral;
class CastExasolFunctionTest {
@Test
void testRendering() {
final Select select = StatementFactory.getInstance().select()
.function(CastExasolFunction.of(NullLiteral.nullLiteral(), new Varchar(254)));
- assertThat(select, rendersTo("SELECT CAST(NULL AS VARCHAR(254))"));
+ assertThat(select, rendersTo("SELECT CAST(NULL AS VARCHAR(254))"));
}
@Test
void testRenderingWithName() {
final Select select = StatementFactory.getInstance().select()
.function(CastExasolFunction.of(NullLiteral.nullLiteral(), new Varchar(254)), "TEST");
- assertThat(select, rendersTo("SELECT CAST(NULL AS VARCHAR(254)) TEST"));
+ assertThat(select, rendersTo("SELECT CAST(NULL AS VARCHAR(254)) TEST"));
}
}
\ No newline at end of file
diff --git a/src/test/java/com/exasol/sql/expression/DoubleLiteralTest.java b/src/test/java/com/exasol/sql/expression/literal/DoubleLiteralTest.java
similarity index 90%
rename from src/test/java/com/exasol/sql/expression/DoubleLiteralTest.java
rename to src/test/java/com/exasol/sql/expression/literal/DoubleLiteralTest.java
index eeea3b9c..ccf4a2fd 100644
--- a/src/test/java/com/exasol/sql/expression/DoubleLiteralTest.java
+++ b/src/test/java/com/exasol/sql/expression/literal/DoubleLiteralTest.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/exasol/sql/expression/FloatLiteralTest.java b/src/test/java/com/exasol/sql/expression/literal/FloatLiteralTest.java
similarity index 90%
rename from src/test/java/com/exasol/sql/expression/FloatLiteralTest.java
rename to src/test/java/com/exasol/sql/expression/literal/FloatLiteralTest.java
index 0e8dd602..20edb852 100644
--- a/src/test/java/com/exasol/sql/expression/FloatLiteralTest.java
+++ b/src/test/java/com/exasol/sql/expression/literal/FloatLiteralTest.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/exasol/sql/expression/LongLiteralTest.java b/src/test/java/com/exasol/sql/expression/literal/LongLiteralTest.java
similarity index 91%
rename from src/test/java/com/exasol/sql/expression/LongLiteralTest.java
rename to src/test/java/com/exasol/sql/expression/literal/LongLiteralTest.java
index 31e13db8..4cf65c24 100644
--- a/src/test/java/com/exasol/sql/expression/LongLiteralTest.java
+++ b/src/test/java/com/exasol/sql/expression/literal/LongLiteralTest.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/exasol/sql/expression/TestBigDecimalLiteral.java b/src/test/java/com/exasol/sql/expression/literal/TestBigDecimalLiteral.java
similarity index 92%
rename from src/test/java/com/exasol/sql/expression/TestBigDecimalLiteral.java
rename to src/test/java/com/exasol/sql/expression/literal/TestBigDecimalLiteral.java
index 39c2ede0..a95e09c6 100644
--- a/src/test/java/com/exasol/sql/expression/TestBigDecimalLiteral.java
+++ b/src/test/java/com/exasol/sql/expression/literal/TestBigDecimalLiteral.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/exasol/sql/expression/TestBooleanLiteral.java b/src/test/java/com/exasol/sql/expression/literal/TestBooleanLiteral.java
similarity index 97%
rename from src/test/java/com/exasol/sql/expression/TestBooleanLiteral.java
rename to src/test/java/com/exasol/sql/expression/literal/TestBooleanLiteral.java
index c06b5953..67a115f2 100644
--- a/src/test/java/com/exasol/sql/expression/TestBooleanLiteral.java
+++ b/src/test/java/com/exasol/sql/expression/literal/TestBooleanLiteral.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/exasol/sql/expression/TestIntegerLiteral.java b/src/test/java/com/exasol/sql/expression/literal/TestIntegerLiteral.java
similarity index 90%
rename from src/test/java/com/exasol/sql/expression/TestIntegerLiteral.java
rename to src/test/java/com/exasol/sql/expression/literal/TestIntegerLiteral.java
index 6f0d71bf..ea714a56 100644
--- a/src/test/java/com/exasol/sql/expression/TestIntegerLiteral.java
+++ b/src/test/java/com/exasol/sql/expression/literal/TestIntegerLiteral.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/exasol/sql/expression/TestStringLiteral.java b/src/test/java/com/exasol/sql/expression/literal/TestStringLiteral.java
similarity index 87%
rename from src/test/java/com/exasol/sql/expression/TestStringLiteral.java
rename to src/test/java/com/exasol/sql/expression/literal/TestStringLiteral.java
index 8145133b..65c8d948 100644
--- a/src/test/java/com/exasol/sql/expression/TestStringLiteral.java
+++ b/src/test/java/com/exasol/sql/expression/literal/TestStringLiteral.java
@@ -1,4 +1,4 @@
-package com.exasol.sql.expression;
+package com.exasol.sql.expression.literal;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/exasol/sql/expression/rendering/TestBooleanExpressionRenderer.java b/src/test/java/com/exasol/sql/expression/rendering/TestBooleanExpressionRenderer.java
index 3e578eef..d72758ba 100644
--- a/src/test/java/com/exasol/sql/expression/rendering/TestBooleanExpressionRenderer.java
+++ b/src/test/java/com/exasol/sql/expression/rendering/TestBooleanExpressionRenderer.java
@@ -1,7 +1,7 @@
package com.exasol.sql.expression.rendering;
-import static com.exasol.hamcrest.BooleanExpressionRenderResultMatcher.rendersTo;
-import static com.exasol.hamcrest.BooleanExpressionRenderResultMatcher.rendersWithConfigTo;
+import static com.exasol.hamcrest.ValueExpressionRenderResultMatcher.rendersTo;
+import static com.exasol.hamcrest.ValueExpressionRenderResultMatcher.rendersWithConfigTo;
import static com.exasol.sql.expression.BooleanTerm.*;
import static com.exasol.sql.expression.ExpressionTerm.*;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -11,9 +11,9 @@
import org.junit.jupiter.api.Test;
-import com.exasol.sql.expression.BigDecimalLiteral;
import com.exasol.sql.expression.BooleanExpression;
import com.exasol.sql.expression.comparison.SimpleComparisonOperator;
+import com.exasol.sql.expression.literal.BigDecimalLiteral;
import com.exasol.sql.rendering.StringRendererConfig;
class TestBooleanExpressionRenderer {
diff --git a/src/test/java/com/exasol/util/DummyBottomUpTreeNode.java b/src/test/java/com/exasol/util/DummyBottomUpTreeNode.java
deleted file mode 100644
index 77a4d426..00000000
--- a/src/test/java/com/exasol/util/DummyBottomUpTreeNode.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.exasol.util;
-
-public class DummyBottomUpTreeNode extends AbstractBottomUpTreeNode {
- public DummyBottomUpTreeNode() {
- super();
- }
-
- public DummyBottomUpTreeNode(final TreeNode... children) {
- super(children);
- }
-}
diff --git a/src/test/java/com/exasol/util/DummyTreeNode.java b/src/test/java/com/exasol/util/DummyTreeNode.java
deleted file mode 100644
index 9ef5afb7..00000000
--- a/src/test/java/com/exasol/util/DummyTreeNode.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.exasol.util;
-
-public class DummyTreeNode extends AbstractTreeNode {
- public DummyTreeNode() {
- super();
- }
-}
diff --git a/src/test/java/com/exasol/util/TestAbstractBottomUpTreeNode.java b/src/test/java/com/exasol/util/TestAbstractBottomUpTreeNode.java
deleted file mode 100644
index 6cceef77..00000000
--- a/src/test/java/com/exasol/util/TestAbstractBottomUpTreeNode.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.exasol.util;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.List;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-class TestAbstractBottomUpTreeNode {
- private TreeNode node;
-
- @BeforeEach
- void beforeEach() {
- this.node = new DummyBottomUpTreeNode();
- }
-
- @Test
- void testIsRootOnRootNode() {
- assertTrue(this.node.isRoot());
- }
-
- @Test
- void testIsChildOnRootNode() {
- assertFalse(this.node.isChild());
- }
-
- @Test
- void testIsFirstSiblingOnRootNode() {
- assertFalse(this.node.isFirstSibling());
- }
-
- @Test
- void testIsRootOnChild() {
- new DummyBottomUpTreeNode(this.node);
- assertFalse(this.node.isRoot());
- }
-
- @Test
- void testIsChildOnChild() {
- new DummyBottomUpTreeNode(this.node);
- assertTrue(this.node.isChild());
- }
-
- @Test
- void testIsFirstSiblingOnChild() {
- new DummyBottomUpTreeNode(this.node);
- assertTrue(this.node.isFirstSibling());
- }
-
- @Test
- void testIsFirstSiblingOnFirstChild() {
- new DummyBottomUpTreeNode(this.node, new DummyBottomUpTreeNode());
- assertTrue(this.node.isFirstSibling());
- }
-
- @Test
- void testIsFirstSiblingOnSecondChild() {
- new DummyBottomUpTreeNode(new DummyBottomUpTreeNode(), this.node);
- assertFalse(this.node.isFirstSibling());
- }
-
- @Test
- void testAddingChildAfterConstructorThrowsException() {
- final DummyBottomUpTreeNode child = new DummyBottomUpTreeNode();
- assertThrows(UnsupportedOperationException.class, () -> this.node.addChild(child));
- }
-
- @Test
- void testGetChildren() {
- final TreeNode otherNode = new DummyBottomUpTreeNode();
- final TreeNode parent = new DummyBottomUpTreeNode(this.node, otherNode);
- assertThat(parent.getChildren(), contains(this.node, otherNode));
- }
-
- @Test
- void testAddingChildToTwoParentsThrowsException() {
- new DummyBottomUpTreeNode(this.node);
- assertThrows(IllegalStateException.class, () -> new DummyBottomUpTreeNode(this.node));
- }
-
- @Test
- void testAddingWrongChildTypeThrowsException() {
- final TreeNode wrongChild = new WrongNodeType();
- assertThrows(IllegalArgumentException.class, () -> new DummyBottomUpTreeNode(wrongChild));
- }
-
- private static class WrongNodeType implements TreeNode {
- @Override
- public TreeNode getRoot() {
- return null;
- }
-
- @Override
- public TreeNode getParent() {
- return null;
- }
-
- @Override
- public void addChild(final TreeNode child) {
- }
-
- @Override
- public List getChildren() {
- return null;
- }
-
- @Override
- public TreeNode getChild(final int index) throws IndexOutOfBoundsException {
- return null;
- }
-
- @Override
- public boolean isRoot() {
- return false;
- }
-
- @Override
- public boolean isChild() {
- return false;
- }
-
- @Override
- public boolean isFirstSibling() {
- return false;
- }
-
- @Override
- public boolean isSibling(final TreeNode node) {
- return false;
- }
-
- @Override
- public void setParent(final TreeNode parent) {
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/com/exasol/util/TestAbstractTreeNode.java b/src/test/java/com/exasol/util/TestAbstractTreeNode.java
deleted file mode 100644
index d2028c65..00000000
--- a/src/test/java/com/exasol/util/TestAbstractTreeNode.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.exasol.util;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
-import static org.junit.jupiter.api.Assertions.*;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-class TestAbstractTreeNode {
- private TreeNode node;
-
- @BeforeEach
- void beforeEach() {
- this.node = new DummyTreeNode();
- }
-
- @Test
- void testIsRootOnRootNode() {
- assertTrue(this.node.isRoot());
- }
-
- @Test
- void testIsChildOnRootNode() {
- assertFalse(this.node.isChild());
- }
-
- @Test
- void testIsFirstSiblingOnRootNode() {
- assertFalse(this.node.isFirstSibling());
- }
-
- @Test
- void testIsRootOnChild() {
- final TreeNode child = new DummyTreeNode();
- this.node.addChild(child);
- assertFalse(child.isRoot());
- }
-
- @Test
- void testIsChildOnChild() {
- final TreeNode child = new DummyTreeNode();
- this.node.addChild(child);
- assertTrue(child.isChild());
- }
-
- @Test
- void testIsFirstSiblingOnChild() {
- final TreeNode child = new DummyTreeNode();
- this.node.addChild(child);
- assertTrue(child.isFirstSibling());
- }
-
- @Test
- void testIsFirstSiblingOnFirstChild() {
- final TreeNode child = new DummyTreeNode();
- final TreeNode otherChild = new DummyTreeNode();
- this.node.addChild(child);
- this.node.addChild(otherChild);
- assertTrue(child.isFirstSibling());
- }
-
- @Test
- void testIsFirstSiblingOnSecondChild() {
- final TreeNode child = new DummyTreeNode();
- final TreeNode otherChild = new DummyTreeNode();
- this.node.addChild(child);
- this.node.addChild(otherChild);
- assertFalse(otherChild.isFirstSibling());
- }
-
- @Test
- void testGetChildren() {
- final TreeNode child = new DummyTreeNode();
- final TreeNode otherChild = new DummyTreeNode();
- this.node.addChild(child);
- this.node.addChild(otherChild);
- assertThat(this.node.getChildren(), contains(child, otherChild));
- }
-
- @Test
- void testGetChild() {
- final TreeNode child = new DummyTreeNode();
- final TreeNode otherChild = new DummyTreeNode();
- this.node.addChild(child);
- this.node.addChild(otherChild);
- assertThat(this.node.getChild(1), equalTo(otherChild));
- }
-
- @Test
- void testGetParent() {
- final TreeNode child = new DummyTreeNode();
- this.node.addChild(child);
- assertThat(child.getParent(), equalTo(this.node));
- }
-
- @Test
- void testSetParentToNullThrowsException() {
- final DummyTreeNode dummyTreeNode = new DummyTreeNode();
- assertThrows(IllegalArgumentException.class, () -> dummyTreeNode.setParent(null));
- }
-
- @Test
- void testSetParentToSelfThrowsException() {
- final DummyTreeNode abstractNode = new DummyTreeNode();
- assertThrows(IllegalArgumentException.class, () -> abstractNode.setParent(abstractNode));
- }
-}
\ No newline at end of file