Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions common/src/main/java/io/druid/math/expr/Evals.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package io.druid.math.expr;

import com.google.common.base.Strings;
import io.druid.common.guava.GuavaUtils;
import io.druid.java.util.common.logger.Logger;

Expand Down Expand Up @@ -81,4 +82,34 @@ public static Expr binaryOp(BinaryOpExprBase binary, Expr left, Expr right)
return binary; // best effort.. keep it working
}
}

public static long asLong(boolean x)
{
return x ? 1L : 0L;
}

public static double asDouble(boolean x)
{
return x ? 1D : 0D;
}

public static String asString(boolean x)
{
return String.valueOf(x);
}

public static boolean asBoolean(long x)
{
return x > 0;
}

public static boolean asBoolean(double x)
{
return x > 0;
}

public static boolean asBoolean(String x)
{
return !Strings.isNullOrEmpty(x) && Boolean.valueOf(x);
}
}
47 changes: 21 additions & 26 deletions common/src/main/java/io/druid/math/expr/Expr.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import io.druid.java.util.common.IAE;

import java.util.List;
import java.util.Objects;

/**
*/
Expand Down Expand Up @@ -242,13 +241,9 @@ class UnaryNotExpr extends UnaryExpr
public ExprEval eval(ObjectBinding bindings)
{
ExprEval ret = expr.eval(bindings);
if (ret.type() == ExprType.LONG) {
return ExprEval.of(ret.asBoolean() ? 0L : 1L);
}
if (ret.type() == ExprType.DOUBLE) {
return ExprEval.of(ret.asBoolean() ? 0.0d :1.0d);
}
throw new IllegalArgumentException("unsupported type " + ret.type());
// conforming to other boolean-returning binary operators
ExprType retType = ret.type() == ExprType.DOUBLE ? ExprType.DOUBLE : ExprType.LONG;
return ExprEval.of(!ret.asBoolean(), retType);
}

@Override
Expand Down Expand Up @@ -458,19 +453,19 @@ class BinLtExpr extends BinaryEvalOpExprBase
@Override
protected ExprEval evalString(String left, String right)
{
return ExprEval.of(left.compareTo(right) < 0 ? 1L : 0L);
return ExprEval.of(left.compareTo(right) < 0, ExprType.LONG);
}

@Override
protected final long evalLong(long left, long right)
{
return left < right ? 1L : 0L;
return Evals.asLong(left < right);
}

@Override
protected final double evalDouble(double left, double right)
{
return left < right ? 1.0d : 0.0d;
return Evals.asDouble(left < right);
}
}

Expand All @@ -484,19 +479,19 @@ class BinLeqExpr extends BinaryEvalOpExprBase
@Override
protected ExprEval evalString(String left, String right)
{
return ExprEval.of(left.compareTo(right) <= 0 ? 1L : 0L);
return ExprEval.of(left.compareTo(right) <= 0, ExprType.LONG);
}

@Override
protected final long evalLong(long left, long right)
{
return left <= right ? 1L : 0L;
return Evals.asLong(left <= right);
}

@Override
protected final double evalDouble(double left, double right)
{
return left <= right ? 1.0d : 0.0d;
return Evals.asDouble(left <= right);
}
}

Expand All @@ -510,19 +505,19 @@ class BinGtExpr extends BinaryEvalOpExprBase
@Override
protected ExprEval evalString(String left, String right)
{
return ExprEval.of(left.compareTo(right) > 0 ? 1L : 0L);
return ExprEval.of(left.compareTo(right) > 0, ExprType.LONG);
}

@Override
protected final long evalLong(long left, long right)
{
return left > right ? 1L : 0L;
return Evals.asLong(left > right);
}

@Override
protected final double evalDouble(double left, double right)
{
return left > right ? 1.0d : 0.0d;
return Evals.asDouble(left > right);
}
}

Expand All @@ -536,19 +531,19 @@ class BinGeqExpr extends BinaryEvalOpExprBase
@Override
protected ExprEval evalString(String left, String right)
{
return ExprEval.of(left.compareTo(right) >= 0 ? 1L : 0L);
return ExprEval.of(left.compareTo(right) >= 0, ExprType.LONG);
}

@Override
protected final long evalLong(long left, long right)
{
return left >= right ? 1L : 0L;
return Evals.asLong(left >= right);
}

@Override
protected final double evalDouble(double left, double right)
{
return left >= right ? 1.0d : 0.0d;
return Evals.asDouble(left >= right);
}
}

Expand All @@ -562,19 +557,19 @@ class BinEqExpr extends BinaryEvalOpExprBase
@Override
protected ExprEval evalString(String left, String right)
{
return ExprEval.of(left.equals(right) ? 1L : 0L);
return ExprEval.of(left.equals(right), ExprType.LONG);
}

@Override
protected final long evalLong(long left, long right)
{
return left == right ? 1L : 0L;
return Evals.asLong(left == right);
}

@Override
protected final double evalDouble(double left, double right)
{
return left == right ? 1.0d : 0.0d;
return Evals.asDouble(left == right);
}
}

Expand All @@ -588,19 +583,19 @@ class BinNeqExpr extends BinaryEvalOpExprBase
@Override
protected ExprEval evalString(String left, String right)
{
return ExprEval.of(!Objects.equals(left, right) ? 1L : 0L);
return ExprEval.of(!left.equals(right), ExprType.LONG);
}

@Override
protected final long evalLong(long left, long right)
{
return left != right ? 1L : 0L;
return Evals.asLong(left != right);
}

@Override
protected final double evalDouble(double left, double right)
{
return left != right ? 1.0d : 0.0d;
return Evals.asDouble(left != right);
}
}

Expand Down
10 changes: 5 additions & 5 deletions common/src/main/java/io/druid/math/expr/ExprEval.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ public static ExprEval of(boolean value, ExprType type)
{
switch (type) {
case DOUBLE:
return ExprEval.of(value ? 1D : 0D);
return ExprEval.of(Evals.asDouble(value));
case LONG:
return ExprEval.of(value ? 1L : 0L);
return ExprEval.of(Evals.asLong(value));
case STRING:
return ExprEval.of(String.valueOf(value));
default:
Expand Down Expand Up @@ -162,7 +162,7 @@ public final ExprType type()
@Override
public final boolean asBoolean()
{
return asDouble() > 0;
return Evals.asBoolean(asDouble());
}

@Override
Expand Down Expand Up @@ -202,7 +202,7 @@ public final ExprType type()
@Override
public final boolean asBoolean()
{
return asLong() > 0;
return Evals.asBoolean(asLong());
}

@Override
Expand Down Expand Up @@ -266,7 +266,7 @@ public final double asDouble()
@Override
public final boolean asBoolean()
{
return Boolean.valueOf(value);
return Evals.asBoolean(value);
}

@Override
Expand Down
31 changes: 31 additions & 0 deletions common/src/test/java/io/druid/math/expr/EvalTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,35 @@ public void testLongEval()
Assert.assertEquals("NULL", eval("nvl(if(x == 9223372036854775807, '', 'x'), 'NULL')", bindings).asString());
Assert.assertEquals("x", eval("nvl(if(x == 9223372036854775806, '', 'x'), 'NULL')", bindings).asString());
}

@Test
public void testBooleanReturn()
{
Expr.ObjectBinding bindings = Parser.withMap(
ImmutableMap.of("x", 100L, "y", 100L, "z", 100D, "w", 100D)
);
ExprEval eval = Parser.parse("x==y").eval(bindings);
Assert.assertTrue(eval.asBoolean());
Assert.assertEquals(ExprType.LONG, eval.type());

eval = Parser.parse("x!=y").eval(bindings);
Assert.assertFalse(eval.asBoolean());
Assert.assertEquals(ExprType.LONG, eval.type());

eval = Parser.parse("x==z").eval(bindings);
Assert.assertTrue(eval.asBoolean());
Assert.assertEquals(ExprType.DOUBLE, eval.type());

eval = Parser.parse("x!=z").eval(bindings);
Assert.assertFalse(eval.asBoolean());
Assert.assertEquals(ExprType.DOUBLE, eval.type());

eval = Parser.parse("z==w").eval(bindings);
Assert.assertTrue(eval.asBoolean());
Assert.assertEquals(ExprType.DOUBLE, eval.type());

eval = Parser.parse("z!=w").eval(bindings);
Assert.assertFalse(eval.asBoolean());
Assert.assertEquals(ExprType.DOUBLE, eval.type());
}
}