diff --git a/src/main/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluator.java b/src/main/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluator.java index 50e36c3..55375a6 100644 --- a/src/main/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluator.java +++ b/src/main/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluator.java @@ -1,5 +1,6 @@ package com.github.sidhant92.boolparser.application; +import static com.github.sidhant92.boolparser.constant.NodeType.UNARY; import java.util.Collections; import java.util.List; import java.util.Map; @@ -72,17 +73,31 @@ private boolean evaluateToken(final Node node, final Map data) { } } - private boolean evaluateComparisonToken(final ComparisonNode comparisonToken, final Map data) { - final Optional fieldDataOptional = ValueUtils.getValueFromMap(comparisonToken.getField(), data); + private Optional getValue(final Node node, final Map data) { + switch (node.getTokenType()) { + case FIELD: + return ValueUtils.getValueFromMap(((FieldNode) node).getField(), data); + case UNARY: + final UnaryNode unaryNode = (UnaryNode) node; + return Optional.of(unaryNode.getValue()); + default: + if (node instanceof ArithmeticBaseNode) { + return Optional.of(arithmeticExpressionEvaluator.evaluate(node, data)); + } + return Optional.of(evaluateToken(node, data)); + } + } - final Object fieldData = comparisonToken.isNullCheck() ? fieldDataOptional.orElse("null") : fieldDataOptional.orElseThrow( - () -> new DataNotFoundException(comparisonToken.getField())); - final Object value = comparisonToken.isNullCheck() ? "null" : comparisonToken.getValue() instanceof ArithmeticBaseNode ? arithmeticExpressionEvaluator.evaluate( - comparisonToken.getValue(), data) : comparisonToken.getValue(); - final DataType dataType = ValueUtils.getDataType(value); - final DataType fieldDataType = ValueUtils.getDataType(fieldData); - return operatorService.evaluateLogicalOperator(comparisonToken.getOperator(), ContainerDataType.PRIMITIVE, fieldData, fieldDataType, - Collections.singletonList(Pair.of(value, dataType))); + private boolean evaluateComparisonToken(final ComparisonNode comparisonToken, final Map data) { + final Optional leftValueOptional = getValue(comparisonToken.getLeft(), data); + + final Object leftData = comparisonToken.isNullCheck() ? leftValueOptional.orElse("null") : leftValueOptional.orElseThrow( + () -> new DataNotFoundException(((FieldNode) comparisonToken.getLeft()).getField())); + final Object rightData = comparisonToken.isNullCheck() ? "null" : getValue(comparisonToken.getRight(), data).get(); + final DataType rightDataType = ValueUtils.getDataType(rightData); + final DataType leftDataType = ValueUtils.getDataType(leftData); + return operatorService.evaluateLogicalOperator(comparisonToken.getOperator(), ContainerDataType.PRIMITIVE, leftData, leftDataType, + Collections.singletonList(Pair.of(rightData, rightDataType))); } private boolean evaluateNumericRangeToken(final NumericRangeNode numericRangeToken, final Map data) { diff --git a/src/main/java/com/github/sidhant92/boolparser/domain/logical/ComparisonNode.java b/src/main/java/com/github/sidhant92/boolparser/domain/logical/ComparisonNode.java index 383e892..74e39c9 100644 --- a/src/main/java/com/github/sidhant92/boolparser/domain/logical/ComparisonNode.java +++ b/src/main/java/com/github/sidhant92/boolparser/domain/logical/ComparisonNode.java @@ -18,9 +18,9 @@ @Setter @Builder public class ComparisonNode extends Node { - private final String field; + private final Node left; - private final Node value; + private final Node right; private final Operator operator; @@ -32,6 +32,6 @@ public NodeType getTokenType() { } public boolean isNullCheck() { - return Operator.getEqualityOperators().contains(this.operator) && this.value instanceof FieldNode && ((FieldNode) this.value).isNull(); + return Operator.getEqualityOperators().contains(this.operator) && (this.right instanceof FieldNode && ((FieldNode) this.right).isNull() || this.left instanceof FieldNode && ((FieldNode) this.left).isNull()); } } diff --git a/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterListener.java b/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterListener.java index 56cdf26..2944fa1 100644 --- a/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterListener.java +++ b/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterListener.java @@ -126,13 +126,17 @@ private Node mapContextToNode(final ParseTree ctx) { } private FieldNode mapTypesExpressionContextField(BooleanExpressionParser.TypesExpressionContext ctx) { - return new FieldNode(ctx.getText()); + final String value = StringUtils.isBlank(ctx.getText()) ? defaultField : ctx.getText(); + return new FieldNode(value); } private Node mapTypesExpressionContext(BooleanExpressionParser.TypesExpressionContext ctx) { if (ctx.start.getType() == BooleanExpressionLexer.FIELD) { return mapTypesExpressionContextField(ctx); } + if (StringUtils.isBlank(ctx.getText())) { + return mapTypesExpressionContextField(ctx); + } final DataType dataType = getDataType(ctx.start); final Object value = ValueUtils.convertValue(ctx.start.getText(), dataType); return new UnaryNode(dataType, value); @@ -150,15 +154,19 @@ private ArithmeticFunctionNode mapArithmeticFunctionExpressionContext(BooleanExp } private ComparisonNode mapComparatorExpressionContext(BooleanExpressionParser.ComparatorExpressionContext ctx) { - final String variableName = getField(ctx.left.getText()); final Operator operator = Operator.getOperatorFromSymbol(ctx.op.getText()).orElse(Operator.EQUALS); if (!(ctx.right instanceof BooleanExpressionParser.TypesExpressionContext) && !currentNodes.isEmpty()) { final Node value = currentNodes.pop(); - return new ComparisonNode(variableName, value, operator, DataType.INTEGER); + return new ComparisonNode(mapContextToNode(ctx.left), value, operator, DataType.INTEGER); } else { + if (ctx.left instanceof BooleanExpressionParser.ParentExpressionContext && !currentNodes.isEmpty()) { + final DataType dataType = getDataType(ctx.right.getStart()); + final Node value = mapContextToNode(ctx.right); + return new ComparisonNode(currentNodes.pop(), value, operator, dataType); + } final DataType dataType = getDataType(ctx.right.getStart()); final Node value = mapContextToNode(ctx.right); - return new ComparisonNode(variableName, value, operator, dataType); + return new ComparisonNode(mapContextToNode(ctx.left), value, operator, dataType); } } diff --git a/src/test/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluatorTest.java b/src/test/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluatorTest.java index 2772608..a3a2f89 100644 --- a/src/test/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluatorTest.java +++ b/src/test/java/com/github/sidhant92/boolparser/application/BooleanExpressionEvaluatorTest.java @@ -112,6 +112,15 @@ public void testNumericGreaterThanCorrectExpression() { assertTrue(booleanOptional.get()); } + @Test + public void testNumericGreaterThanCorrectExpressionInverted() { + final Map data = new HashMap<>(); + data.put("age", 24); + final Try booleanOptional = booleanExpressionEvaluator.evaluate("20 < age", data); + assertTrue(booleanOptional.isSuccess()); + assertTrue(booleanOptional.get()); + } + @Test public void testNumericGreaterThanCorrectExpressionWithField() { final Map data = new HashMap<>(); @@ -553,6 +562,15 @@ public void testComparisonWithArithmeticTrueCondition() { assertTrue(booleanOptional.get()); } + @Test + public void testComparisonWithArithmeticTrueConditionInverted() { + final Map data = new HashMap<>(); + data.put("age", "20"); + final Try booleanOptional = booleanExpressionEvaluator.evaluate("(5 + 10) < age", data); + assertTrue(booleanOptional.isSuccess()); + assertTrue(booleanOptional.get()); + } + @Test public void testComparisonWithArithmeticFunction() { final Map data = new HashMap<>(); @@ -614,6 +632,15 @@ public void testNullCheck() { assertEquals(resultOptional.get(), true); } + @Test + public void testNullCheckInverted() { + final Map data = new HashMap<>(); + data.put("a", 2.7); + final Try resultOptional = booleanExpressionEvaluator.evaluate("null = b", data); + assertTrue(resultOptional.isSuccess()); + assertEquals(resultOptional.get(), true); + } + @Test public void testNullCheck1() { final Map data = new HashMap<>(); @@ -640,4 +667,13 @@ public void testBooleanNullCheck() { assertTrue(resultOptional.isSuccess()); assertEquals(resultOptional.get(), true); } + + @Test + public void testArithmeticFunctionAndComparison() { + final Map data = new HashMap<>(); + data.put("a", "test"); + final Try resultOptional = booleanExpressionEvaluator.evaluate("len(a) = 4", data); + assertTrue(resultOptional.isSuccess()); + assertEquals(resultOptional.get(), true); + } } diff --git a/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java b/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java index 2fb4988..ab3a9c0 100644 --- a/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java +++ b/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java @@ -54,7 +54,7 @@ public void testSingleStringToken() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("name = 'test'"); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), "test", DataType.STRING); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), "test", DataType.STRING); } @Test @@ -62,7 +62,7 @@ public void testSingleStringTokenWithSingleQuotes() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("name = \"te\'st\""); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), "te'st", DataType.STRING); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), "te'st", DataType.STRING); } @Test @@ -70,7 +70,7 @@ public void testSingleStringTokenWithDoubleQuotes() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("name = 'te\"st'"); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), "te\"st", DataType.STRING); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), "te\"st", DataType.STRING); } @Test @@ -78,7 +78,7 @@ public void testSingleStringTokenWithSpace() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("name = \"first second\""); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), "first second", DataType.STRING); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), "first second", DataType.STRING); } @Test @@ -86,7 +86,7 @@ public void testSingleIntToken() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("age=44"); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "age", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), 44, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), 44, DataType.INTEGER); } @Test @@ -94,7 +94,7 @@ public void testSingleLongToken() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("age=1611473334114"); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "age", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), 1611473334114L, DataType.LONG); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), 1611473334114L, DataType.LONG); } @Test @@ -102,7 +102,7 @@ public void testSingleDecimalToken() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("age=44.34"); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "age", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), new BigDecimal("44.34"), DataType.DECIMAL); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), new BigDecimal("44.34"), DataType.DECIMAL); } @Test @@ -118,7 +118,7 @@ public void testGreaterThan() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("age > 18"); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "age", Operator.GREATER_THAN); - verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getValue(), 18, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode) nodeOptional.get()).getRight(), 18, DataType.INTEGER); } @Test @@ -126,7 +126,7 @@ public void testGreaterThanWithField() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("age > a"); assertTrue(nodeOptional.isSuccess()); verifyComparisonToken(nodeOptional.get(), "age", Operator.GREATER_THAN); - verifyFieldToken(((ComparisonNode) nodeOptional.get()).getValue(), "a"); + verifyFieldToken(((ComparisonNode) nodeOptional.get()).getRight(), "a"); } @Test @@ -149,9 +149,9 @@ public void testSimpleOrCondition() { assertEquals(booleanToken.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(booleanToken.getRight().getTokenType().name(), NodeType.COMPARISON.name()); verifyComparisonToken(((BooleanNode) nodeOptional.get()).getLeft(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getValue(), "test", DataType.STRING); + verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getRight(), "test", DataType.STRING); verifyComparisonToken(((BooleanNode) nodeOptional.get()).getRight(), "age", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getRight()).getValue(), 33, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getRight()).getRight(), 33, DataType.INTEGER); } @Test @@ -166,9 +166,9 @@ public void testSimpleAndCondition() { assertEquals(booleanToken.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(booleanToken.getRight().getTokenType().name(), NodeType.COMPARISON.name()); verifyComparisonToken(((BooleanNode) nodeOptional.get()).getLeft(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getValue(), "test", DataType.STRING); + verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getRight(), "test", DataType.STRING); verifyComparisonToken(((BooleanNode) nodeOptional.get()).getRight(), "age", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getRight()).getValue(), 33, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getRight()).getRight(), 33, DataType.INTEGER); } @Test @@ -182,7 +182,7 @@ public void testSimpleNotCondition() { assertEquals(booleanToken.getOperator(), LogicalOperationType.NOT); assertEquals(booleanToken.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); verifyComparisonToken(((BooleanNode) nodeOptional.get()).getLeft(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getValue(), "test", DataType.STRING); + verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getRight(), "test", DataType.STRING); } @Test @@ -197,7 +197,7 @@ public void testNestedAndCondition() { assertEquals(booleanToken.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(booleanToken.getRight().getTokenType().name(), NodeType.BOOLEAN.name()); verifyComparisonToken(booleanToken.getLeft(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getValue(), "test", DataType.STRING); + verifyUnaryToken(((ComparisonNode)((BooleanNode) nodeOptional.get()).getLeft()).getRight(), "test", DataType.STRING); final BooleanNode nestedBooleanExpression = (BooleanNode) booleanToken.getRight(); assertNotNull(nestedBooleanExpression.getLeft()); assertNotNull(nestedBooleanExpression.getRight()); @@ -205,9 +205,9 @@ public void testNestedAndCondition() { assertEquals(nestedBooleanExpression.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(nestedBooleanExpression.getRight().getTokenType().name(), NodeType.COMPARISON.name()); verifyComparisonToken(nestedBooleanExpression.getLeft(), "age", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nestedBooleanExpression.getLeft()).getValue(), 33, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode) nestedBooleanExpression.getLeft()).getRight(), 33, DataType.INTEGER); verifyComparisonToken(nestedBooleanExpression.getRight(), "city", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode) nestedBooleanExpression.getRight()).getValue(), "dummy", DataType.STRING); + verifyUnaryToken(((ComparisonNode) nestedBooleanExpression.getRight()).getRight(), "dummy", DataType.STRING); } @Test @@ -228,9 +228,9 @@ public void testNestedAndCondition1() { assertEquals(nestedLeftBooleanExpression.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(nestedLeftBooleanExpression.getRight().getTokenType().name(), NodeType.COMPARISON.name()); verifyComparisonToken(nestedLeftBooleanExpression.getLeft(), "agel", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)nestedLeftBooleanExpression.getLeft()).getValue(), 44, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode)nestedLeftBooleanExpression.getLeft()).getRight(), 44, DataType.INTEGER); verifyComparisonToken(nestedLeftBooleanExpression.getRight(), "cityl", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)nestedLeftBooleanExpression.getRight()).getValue(), "abc", DataType.STRING); + verifyUnaryToken(((ComparisonNode)nestedLeftBooleanExpression.getRight()).getRight(), "abc", DataType.STRING); final BooleanNode nestedRightBooleanExpression = (BooleanNode) booleanToken.getRight(); assertNotNull(nestedRightBooleanExpression.getLeft()); assertNotNull(nestedRightBooleanExpression.getRight()); @@ -238,9 +238,9 @@ public void testNestedAndCondition1() { assertEquals(nestedRightBooleanExpression.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(nestedRightBooleanExpression.getRight().getTokenType().name(), NodeType.COMPARISON.name()); verifyComparisonToken(nestedRightBooleanExpression.getLeft(), "ager", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)nestedRightBooleanExpression.getLeft()).getValue(), 33, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode)nestedRightBooleanExpression.getLeft()).getRight(), 33, DataType.INTEGER); verifyComparisonToken(nestedRightBooleanExpression.getRight(), "cityr", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)nestedRightBooleanExpression.getRight()).getValue(), "dummy", DataType.STRING); + verifyUnaryToken(((ComparisonNode)nestedRightBooleanExpression.getRight()).getRight(), "dummy", DataType.STRING); } @Test @@ -255,7 +255,7 @@ public void testNestedOrCondition() { assertEquals(booleanToken.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(booleanToken.getRight().getTokenType().name(), NodeType.BOOLEAN.name()); verifyComparisonToken(booleanToken.getLeft(), "name", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)booleanToken.getLeft()).getValue(), "test", DataType.STRING); + verifyUnaryToken(((ComparisonNode)booleanToken.getLeft()).getRight(), "test", DataType.STRING); final BooleanNode nestedBooleanExpression = (BooleanNode) booleanToken.getRight(); assertNotNull(nestedBooleanExpression.getLeft()); assertNotNull(nestedBooleanExpression.getRight()); @@ -263,9 +263,9 @@ public void testNestedOrCondition() { assertEquals(nestedBooleanExpression.getLeft().getTokenType().name(), NodeType.COMPARISON.name()); assertEquals(nestedBooleanExpression.getRight().getTokenType().name(), NodeType.COMPARISON.name()); verifyComparisonToken(nestedBooleanExpression.getLeft(), "age", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)nestedBooleanExpression.getLeft()).getValue(), 33, DataType.INTEGER); + verifyUnaryToken(((ComparisonNode)nestedBooleanExpression.getLeft()).getRight(), 33, DataType.INTEGER); verifyComparisonToken(nestedBooleanExpression.getRight(), "city", Operator.EQUALS); - verifyUnaryToken(((ComparisonNode)nestedBooleanExpression.getRight()).getValue(), "dummy", DataType.STRING); + verifyUnaryToken(((ComparisonNode)nestedBooleanExpression.getRight()).getRight(), "dummy", DataType.STRING); } @Test @@ -457,8 +457,8 @@ public void testComparisonWithArithmetic() { final Try nodeOptional = boolExpressionBoolParser.parseExpression("a > (10 + 20)"); assertTrue(nodeOptional.isSuccess()); assertEquals(nodeOptional.get().getTokenType(), NodeType.COMPARISON); - assertEquals((((ComparisonNode) nodeOptional.get()).getField()), "a"); - final ArithmeticNode arithmeticNode = (ArithmeticNode) ((ComparisonNode) nodeOptional.get()).getValue(); + assertEquals(((FieldNode)(((ComparisonNode) nodeOptional.get()).getLeft())).getField(), "a"); + final ArithmeticNode arithmeticNode = (ArithmeticNode) ((ComparisonNode) nodeOptional.get()).getRight(); assertEquals(((UnaryNode) (arithmeticNode.getLeft())).getValue(), 10); assertEquals(((UnaryNode) (arithmeticNode.getLeft())).getDataType(), DataType.INTEGER); assertEquals(((UnaryNode) (arithmeticNode.getRight())).getValue(), 20); @@ -479,7 +479,7 @@ private void verifyFieldToken(final Node node, final Object value) { private void verifyComparisonToken(final Node node, final String field, final Operator operator) { assertEquals(node.getTokenType().name(), NodeType.COMPARISON.name()); - assertEquals(((ComparisonNode)node).getField(), field); + assertEquals(((FieldNode)((ComparisonNode)node).getLeft()).getField(), field); assertEquals(((ComparisonNode)node).getOperator(), operator); }