ExpressionEvaluatorImpl implements ExpressionEvaluator { private <T extends Comparable<? super T>> T evaluateUnaryArithmeticExpression(UnaryArithmeticExpression unaryArithmeticExpression, DataRow dataRow) { Object value = unaryArithmeticExpression.getValue(); if (value == null) { throw new IllegalArgumentException("Nulls are not allowed in arithmetic expressions"); } Class<?> valueClass = value.getClass(); UnaryArithmeticOperator unaryArithmeticOperator = unaryArithmeticExpression.getUnaryArithmeticOperator(); if (!isConstant(valueClass)) { return evaluateUnaryArithmeticExpression(new UnaryArithmeticExpression(evaluate(value, dataRow), unaryArithmeticOperator), dataRow); } if (!isNumber(valueClass)) { throw new IllegalArgumentException(String.format( "Arithmetic expression can contain only numbers: %s %s", unaryArithmeticOperator.getText(), value )); } switch (unaryArithmeticOperator) { default: case PLUS: return isInteger(valueClass) ? cast(+asInt(value), Integer.class, Comparable.class) : cast(+asDouble(value), Double.class, Comparable.class) ; case MINUS: return isInteger(valueClass) ? cast(-asInt(value), Integer.class, Comparable.class) : cast(-asDouble(value), Double.class, Comparable.class) ; case BIT_NOT: { if (!isInteger(valueClass)) { throw new IllegalArgumentException(String.format( "Bitwise NOT operation is only applicable to integers: %s %s", unaryArithmeticOperator.getText(), value )); } return cast(~asInt(value), Integer.class, Comparable.class); } } }  @Override Map<String, Set<String>> getColumnNames(Object expression); @Override T evaluate(Object expression, DataRow dataRow); @Override T evaluateAs(Object expression, DataRow dataRow, Class<T> cls);  }
@Test public void testEvaluateUnaryArithmeticExpression() { assertThat(arithmetic(1, UnaryArithmeticOperator.PLUS, Integer.class), equalTo(1)); assertThat(arithmetic(2d, UnaryArithmeticOperator.PLUS, Double.class), equalTo(2d)); assertThat(arithmetic(1, UnaryArithmeticOperator.MINUS, Integer.class), equalTo(-1)); assertThat(arithmetic(column(NUMERIC_COLUMN_NAME, TABLE_NAME), UnaryArithmeticOperator.MINUS, ROW_WITH_VALUES, Double.class), equalTo(3d)); assertThat(arithmetic(1, BIT_NOT, Integer.class), equalTo(-2)); }