diff --git a/core/src/main/java/org/apache/druid/math/expr/BinaryLogicalOperatorExpr.java b/core/src/main/java/org/apache/druid/math/expr/BinaryLogicalOperatorExpr.java
new file mode 100644
index 0000000..dad35f3
--- /dev/null
+++ b/core/src/main/java/org/apache/druid/math/expr/BinaryLogicalOperatorExpr.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.math.expr;
+
+import org.apache.druid.java.util.common.guava.Comparators;
+
+import javax.annotation.Nullable;
+import java.util.Objects;
+
+// logical operators live here
+
+class BinLtExpr extends BinaryEvalOpExprBase
+{
+  BinLtExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinLtExpr(op, left, right);
+  }
+
+  @Override
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) < 0, ExprType.LONG);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return Evals.asLong(left < right);
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    // Use Double.compare for more consistent NaN handling.
+    return Evals.asDouble(Double.compare(left, right) < 0);
+  }
+}
+
+class BinLeqExpr extends BinaryEvalOpExprBase
+{
+  BinLeqExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinLeqExpr(op, left, right);
+  }
+
+  @Override
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) <= 0, ExprType.LONG);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return Evals.asLong(left <= right);
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    // Use Double.compare for more consistent NaN handling.
+    return Evals.asDouble(Double.compare(left, right) <= 0);
+  }
+}
+
+class BinGtExpr extends BinaryEvalOpExprBase
+{
+  BinGtExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinGtExpr(op, left, right);
+  }
+
+  @Override
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) > 0, ExprType.LONG);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return Evals.asLong(left > right);
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    // Use Double.compare for more consistent NaN handling.
+    return Evals.asDouble(Double.compare(left, right) > 0);
+  }
+}
+
+class BinGeqExpr extends BinaryEvalOpExprBase
+{
+  BinGeqExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinGeqExpr(op, left, right);
+  }
+
+  @Override
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) >= 0, ExprType.LONG);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return Evals.asLong(left >= right);
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    // Use Double.compare for more consistent NaN handling.
+    return Evals.asDouble(Double.compare(left, right) >= 0);
+  }
+}
+
+class BinEqExpr extends BinaryEvalOpExprBase
+{
+  BinEqExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinEqExpr(op, left, right);
+  }
+
+  @Override
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    return ExprEval.of(Objects.equals(left, right), ExprType.LONG);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return Evals.asLong(left == right);
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return Evals.asDouble(left == right);
+  }
+}
+
+class BinNeqExpr extends BinaryEvalOpExprBase
+{
+  BinNeqExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinNeqExpr(op, left, right);
+  }
+
+  @Override
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    return ExprEval.of(!Objects.equals(left, right), ExprType.LONG);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return Evals.asLong(left != right);
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return Evals.asDouble(left != right);
+  }
+}
+
+class BinAndExpr extends BinaryOpExprBase
+{
+  BinAndExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinAndExpr(op, left, right);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    ExprEval leftVal = left.eval(bindings);
+    return leftVal.asBoolean() ? right.eval(bindings) : leftVal;
+  }
+}
+
+class BinOrExpr extends BinaryOpExprBase
+{
+  BinOrExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinOrExpr(op, left, right);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    ExprEval leftVal = left.eval(bindings);
+    return leftVal.asBoolean() ? leftVal : right.eval(bindings);
+  }
+
+}
diff --git a/core/src/main/java/org/apache/druid/math/expr/BinaryMathOperatorExpr.java b/core/src/main/java/org/apache/druid/math/expr/BinaryMathOperatorExpr.java
new file mode 100644
index 0000000..21fadd4
--- /dev/null
+++ b/core/src/main/java/org/apache/druid/math/expr/BinaryMathOperatorExpr.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.math.expr;
+
+import com.google.common.math.LongMath;
+import com.google.common.primitives.Ints;
+import org.apache.druid.common.config.NullHandling;
+
+import javax.annotation.Nullable;
+
+// math operators live here
+
+class BinPlusExpr extends BinaryEvalOpExprBase
+{
+  BinPlusExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinPlusExpr(op, left, right);
+  }
+
+  @Override
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    return ExprEval.of(NullHandling.nullToEmptyIfNeeded(left)
+                       + NullHandling.nullToEmptyIfNeeded(right));
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return left + right;
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return left + right;
+  }
+}
+
+class BinMinusExpr extends BinaryEvalOpExprBase
+{
+  BinMinusExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinMinusExpr(op, left, right);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return left - right;
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return left - right;
+  }
+}
+
+class BinMulExpr extends BinaryEvalOpExprBase
+{
+  BinMulExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinMulExpr(op, left, right);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return left * right;
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return left * right;
+  }
+}
+
+class BinDivExpr extends BinaryEvalOpExprBase
+{
+  BinDivExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinDivExpr(op, left, right);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return left / right;
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return left / right;
+  }
+}
+
+class BinPowExpr extends BinaryEvalOpExprBase
+{
+  BinPowExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinPowExpr(op, left, right);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return LongMath.pow(left, Ints.checkedCast(right));
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return Math.pow(left, right);
+  }
+}
+
+class BinModuloExpr extends BinaryEvalOpExprBase
+{
+  BinModuloExpr(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  protected BinaryOpExprBase copy(Expr left, Expr right)
+  {
+    return new BinModuloExpr(op, left, right);
+  }
+
+  @Override
+  protected final long evalLong(long left, long right)
+  {
+    return left % right;
+  }
+
+  @Override
+  protected final double evalDouble(double left, double right)
+  {
+    return left % right;
+  }
+}
diff --git a/core/src/main/java/org/apache/druid/math/expr/BinaryOperatorExpr.java b/core/src/main/java/org/apache/druid/math/expr/BinaryOperatorExpr.java
new file mode 100644
index 0000000..9c39058
--- /dev/null
+++ b/core/src/main/java/org/apache/druid/math/expr/BinaryOperatorExpr.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.math.expr;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.druid.common.config.NullHandling;
+import org.apache.druid.java.util.common.StringUtils;
+
+import javax.annotation.Nullable;
+import java.util.Objects;
+
+/**
+ * Base type for all binary operators, this {@link Expr} has two children {@link Expr} for the left and right side
+ * operands.
+ *
+ * Note: all concrete subclass of this should have constructor with the form of <init>(String, Expr, Expr)
+ * if it's not possible, just be sure Evals.binaryOp() can handle that
+ */
+abstract class BinaryOpExprBase implements Expr
+{
+  protected final String op;
+  protected final Expr left;
+  protected final Expr right;
+
+  BinaryOpExprBase(String op, Expr left, Expr right)
+  {
+    this.op = op;
+    this.left = left;
+    this.right = right;
+  }
+
+  @Override
+  public void visit(Visitor visitor)
+  {
+    left.visit(visitor);
+    right.visit(visitor);
+    visitor.visit(this);
+  }
+
+  @Override
+  public Expr visit(Shuttle shuttle)
+  {
+    Expr newLeft = left.visit(shuttle);
+    Expr newRight = right.visit(shuttle);
+    //noinspection ObjectEquality (checking for object equality here is intentional)
+    if (left != newLeft || right != newRight) {
+      return shuttle.visit(copy(newLeft, newRight));
+    }
+    return shuttle.visit(this);
+  }
+
+  @Override
+  public String toString()
+  {
+    return StringUtils.format("(%s %s %s)", op, left, right);
+  }
+
+  @Override
+  public String stringify()
+  {
+    return StringUtils.format("(%s %s %s)", left.stringify(), op, right.stringify());
+  }
+
+  protected abstract BinaryOpExprBase copy(Expr left, Expr right);
+
+  @Override
+  public BindingDetails analyzeInputs()
+  {
+    // currently all binary operators operate on scalar inputs
+    return left.analyzeInputs().with(right).withScalarArguments(ImmutableSet.of(left, right));
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    BinaryOpExprBase that = (BinaryOpExprBase) o;
+    return Objects.equals(op, that.op) &&
+           Objects.equals(left, that.left) &&
+           Objects.equals(right, that.right);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(op, left, right);
+  }
+}
+
+/**
+ * Base class for numerical binary operators, with additional methods defined to evaluate primitive values directly
+ * instead of wrapped with {@link ExprEval}
+ */
+abstract class BinaryEvalOpExprBase extends BinaryOpExprBase
+{
+  BinaryEvalOpExprBase(String op, Expr left, Expr right)
+  {
+    super(op, left, right);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    ExprEval leftVal = left.eval(bindings);
+    ExprEval rightVal = right.eval(bindings);
+
+    // Result of any Binary expressions is null if any of the argument is null.
+    // e.g "select null * 2 as c;" or "select null + 1 as c;" will return null as per Standard SQL spec.
+    if (NullHandling.sqlCompatible() && (leftVal.value() == null || rightVal.value() == null)) {
+      return ExprEval.of(null);
+    }
+
+    if (leftVal.type() == ExprType.STRING && rightVal.type() == ExprType.STRING) {
+      return evalString(leftVal.asString(), rightVal.asString());
+    } else if (leftVal.type() == ExprType.LONG && rightVal.type() == ExprType.LONG) {
+      if (NullHandling.sqlCompatible() && (leftVal.isNumericNull() || rightVal.isNumericNull())) {
+        return ExprEval.of(null);
+      }
+      return ExprEval.of(evalLong(leftVal.asLong(), rightVal.asLong()));
+    } else {
+      if (NullHandling.sqlCompatible() && (leftVal.isNumericNull() || rightVal.isNumericNull())) {
+        return ExprEval.of(null);
+      }
+      return ExprEval.of(evalDouble(leftVal.asDouble(), rightVal.asDouble()));
+    }
+  }
+
+  protected ExprEval evalString(@Nullable String left, @Nullable String right)
+  {
+    throw new IllegalArgumentException("unsupported type " + ExprType.STRING);
+  }
+
+  protected abstract long evalLong(long left, long right);
+
+  protected abstract double evalDouble(double left, double right);
+}
diff --git a/core/src/main/java/org/apache/druid/math/expr/ConstantExpr.java b/core/src/main/java/org/apache/druid/math/expr/ConstantExpr.java
new file mode 100644
index 0000000..4f6099c
--- /dev/null
+++ b/core/src/main/java/org/apache/druid/math/expr/ConstantExpr.java
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.math.expr;
+
+import com.google.common.base.Preconditions;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.druid.common.config.NullHandling;
+import org.apache.druid.java.util.common.StringUtils;
+
+import javax.annotation.Nullable;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Base type for all constant expressions. {@link ConstantExpr} allow for direct value extraction without evaluating
+ * {@link Expr.ObjectBinding}. {@link ConstantExpr} are terminal nodes of an expression tree, and have no children
+ * {@link Expr}.
+ */
+abstract class ConstantExpr implements Expr
+{
+  @Override
+  public boolean isLiteral()
+  {
+    return true;
+  }
+
+  @Override
+  public void visit(Visitor visitor)
+  {
+    visitor.visit(this);
+  }
+
+  @Override
+  public Expr visit(Shuttle shuttle)
+  {
+    return shuttle.visit(this);
+  }
+
+  @Override
+  public BindingDetails analyzeInputs()
+  {
+    return new BindingDetails();
+  }
+
+  @Override
+  public String stringify()
+  {
+    return toString();
+  }
+}
+
+/**
+ * Base class for typed 'null' value constants (or default value, depending on {@link NullHandling#sqlCompatible})
+ */
+abstract class NullNumericConstantExpr extends ConstantExpr
+{
+  @Override
+  public Object getLiteralValue()
+  {
+    return null;
+  }
+
+  @Override
+  public String toString()
+  {
+    return NULL_LITERAL;
+  }
+}
+
+class LongExpr extends ConstantExpr
+{
+  private final Long value;
+
+  LongExpr(Long value)
+  {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+
+  @Override
+  public Object getLiteralValue()
+  {
+    return value;
+  }
+
+  @Override
+  public String toString()
+  {
+    return String.valueOf(value);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.ofLong(value);
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    LongExpr longExpr = (LongExpr) o;
+    return Objects.equals(value, longExpr.value);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(value);
+  }
+}
+
+class NullLongExpr extends NullNumericConstantExpr
+{
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.ofLong(null);
+  }
+
+  @Override
+  public final int hashCode()
+  {
+    return NullLongExpr.class.hashCode();
+  }
+
+  @Override
+  public final boolean equals(Object obj)
+  {
+    return obj instanceof NullLongExpr;
+  }
+}
+
+class LongArrayExpr extends ConstantExpr
+{
+  private final Long[] value;
+
+  LongArrayExpr(Long[] value)
+  {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+
+  @Override
+  public Object getLiteralValue()
+  {
+    return value;
+  }
+
+  @Override
+  public String toString()
+  {
+    return Arrays.toString(value);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.ofLongArray(value);
+  }
+
+  @Override
+  public String stringify()
+  {
+    if (value.length == 0) {
+      return "<LONG>[]";
+    }
+    return StringUtils.format("<LONG>%s", toString());
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    LongArrayExpr that = (LongArrayExpr) o;
+    return Arrays.equals(value, that.value);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Arrays.hashCode(value);
+  }
+}
+
+class StringExpr extends ConstantExpr
+{
+  @Nullable
+  private final String value;
+
+  StringExpr(@Nullable String value)
+  {
+    this.value = NullHandling.emptyToNullIfNeeded(value);
+  }
+
+  @Nullable
+  @Override
+  public Object getLiteralValue()
+  {
+    return value;
+  }
+
+  @Override
+  public String toString()
+  {
+    return value;
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.of(value);
+  }
+
+  @Override
+  public String stringify()
+  {
+    // escape as javascript string since string literals are wrapped in single quotes
+    return value == null ? NULL_LITERAL : StringUtils.format("'%s'", StringEscapeUtils.escapeJavaScript(value));
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    StringExpr that = (StringExpr) o;
+    return Objects.equals(value, that.value);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(value);
+  }
+}
+
+class StringArrayExpr extends ConstantExpr
+{
+  private final String[] value;
+
+  StringArrayExpr(String[] value)
+  {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+
+  @Override
+  public Object getLiteralValue()
+  {
+    return value;
+  }
+
+  @Override
+  public String toString()
+  {
+    return Arrays.toString(value);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.ofStringArray(value);
+  }
+
+  @Override
+  public String stringify()
+  {
+    if (value.length == 0) {
+      return "<STRING>[]";
+    }
+
+    return StringUtils.format(
+        "<STRING>[%s]",
+        ARG_JOINER.join(
+            Arrays.stream(value)
+                  .map(s -> s == null
+                            ? NULL_LITERAL
+                            // escape as javascript string since string literals are wrapped in single quotes
+                            : StringUtils.format("'%s'", StringEscapeUtils.escapeJavaScript(s))
+                  )
+                  .iterator()
+        )
+    );
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    StringArrayExpr that = (StringArrayExpr) o;
+    return Arrays.equals(value, that.value);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Arrays.hashCode(value);
+  }
+}
+
+class DoubleExpr extends ConstantExpr
+{
+  private final Double value;
+
+  DoubleExpr(Double value)
+  {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+
+  @Override
+  public Object getLiteralValue()
+  {
+    return value;
+  }
+
+  @Override
+  public String toString()
+  {
+    return String.valueOf(value);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.ofDouble(value);
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    DoubleExpr that = (DoubleExpr) o;
+    return Objects.equals(value, that.value);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(value);
+  }
+}
+
+class NullDoubleExpr extends NullNumericConstantExpr
+{
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.ofDouble(null);
+  }
+
+  @Override
+  public final int hashCode()
+  {
+    return NullDoubleExpr.class.hashCode();
+  }
+
+  @Override
+  public final boolean equals(Object obj)
+  {
+    return obj instanceof NullDoubleExpr;
+  }
+}
+
+class DoubleArrayExpr extends ConstantExpr
+{
+  private final Double[] value;
+
+  DoubleArrayExpr(Double[] value)
+  {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+
+  @Override
+  public Object getLiteralValue()
+  {
+    return value;
+  }
+
+  @Override
+  public String toString()
+  {
+    return Arrays.toString(value);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.ofDoubleArray(value);
+  }
+
+  @Override
+  public String stringify()
+  {
+    if (value.length == 0) {
+      return "<DOUBLE>[]";
+    }
+    return StringUtils.format("<DOUBLE>%s", toString());
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    DoubleArrayExpr that = (DoubleArrayExpr) o;
+    return Arrays.equals(value, that.value);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Arrays.hashCode(value);
+  }
+}
diff --git a/core/src/main/java/org/apache/druid/math/expr/Expr.java b/core/src/main/java/org/apache/druid/math/expr/Expr.java
index 1cd7d62..e0a1525 100644
--- a/core/src/main/java/org/apache/druid/math/expr/Expr.java
+++ b/core/src/main/java/org/apache/druid/math/expr/Expr.java
@@ -20,28 +20,16 @@
 package org.apache.druid.math.expr;
 
 import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
-import com.google.common.math.LongMath;
-import com.google.common.primitives.Ints;
-import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.druid.annotations.SubclassesMustOverrideEqualsAndHashCode;
-import org.apache.druid.common.config.NullHandling;
-import org.apache.druid.java.util.common.IAE;
 import org.apache.druid.java.util.common.ISE;
-import org.apache.druid.java.util.common.StringUtils;
-import org.apache.druid.java.util.common.guava.Comparators;
 
 import javax.annotation.Nullable;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * Base interface of Druid expression language abstract syntax tree nodes. All {@link Expr} implementations are
@@ -444,1533 +432,3 @@
     }
   }
 }
-
-/**
- * Base type for all constant expressions. {@link ConstantExpr} allow for direct value extraction without evaluating
- * {@link Expr.ObjectBinding}. {@link ConstantExpr} are terminal nodes of an expression tree, and have no children
- * {@link Expr}.
- */
-abstract class ConstantExpr implements Expr
-{
-  @Override
-  public boolean isLiteral()
-  {
-    return true;
-  }
-
-  @Override
-  public void visit(Visitor visitor)
-  {
-    visitor.visit(this);
-  }
-
-  @Override
-  public Expr visit(Shuttle shuttle)
-  {
-    return shuttle.visit(this);
-  }
-
-  @Override
-  public BindingDetails analyzeInputs()
-  {
-    return new BindingDetails();
-  }
-
-  @Override
-  public String stringify()
-  {
-    return toString();
-  }
-}
-
-abstract class NullNumericConstantExpr extends ConstantExpr
-{
-  @Override
-  public Object getLiteralValue()
-  {
-    return null;
-  }
-
-  @Override
-  public String toString()
-  {
-    return NULL_LITERAL;
-  }
-}
-
-class LongExpr extends ConstantExpr
-{
-  private final Long value;
-
-  LongExpr(Long value)
-  {
-    this.value = Preconditions.checkNotNull(value, "value");
-  }
-
-  @Override
-  public Object getLiteralValue()
-  {
-    return value;
-  }
-
-  @Override
-  public String toString()
-  {
-    return String.valueOf(value);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.ofLong(value);
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    LongExpr longExpr = (LongExpr) o;
-    return Objects.equals(value, longExpr.value);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(value);
-  }
-}
-
-class NullLongExpr extends NullNumericConstantExpr
-{
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.ofLong(null);
-  }
-
-  @Override
-  public final int hashCode()
-  {
-    return NullLongExpr.class.hashCode();
-  }
-
-  @Override
-  public final boolean equals(Object obj)
-  {
-    return obj instanceof NullLongExpr;
-  }
-}
-
-
-class LongArrayExpr extends ConstantExpr
-{
-  private final Long[] value;
-
-  LongArrayExpr(Long[] value)
-  {
-    this.value = Preconditions.checkNotNull(value, "value");
-  }
-
-  @Override
-  public Object getLiteralValue()
-  {
-    return value;
-  }
-
-  @Override
-  public String toString()
-  {
-    return Arrays.toString(value);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.ofLongArray(value);
-  }
-
-  @Override
-  public String stringify()
-  {
-    if (value.length == 0) {
-      return "<LONG>[]";
-    }
-    return StringUtils.format("<LONG>%s", toString());
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    LongArrayExpr that = (LongArrayExpr) o;
-    return Arrays.equals(value, that.value);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Arrays.hashCode(value);
-  }
-}
-
-class StringExpr extends ConstantExpr
-{
-  @Nullable
-  private final String value;
-
-  StringExpr(@Nullable String value)
-  {
-    this.value = NullHandling.emptyToNullIfNeeded(value);
-  }
-
-  @Nullable
-  @Override
-  public Object getLiteralValue()
-  {
-    return value;
-  }
-
-  @Override
-  public String toString()
-  {
-    return value;
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.of(value);
-  }
-
-  @Override
-  public String stringify()
-  {
-    // escape as javascript string since string literals are wrapped in single quotes
-    return value == null ? NULL_LITERAL : StringUtils.format("'%s'", StringEscapeUtils.escapeJavaScript(value));
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    StringExpr that = (StringExpr) o;
-    return Objects.equals(value, that.value);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(value);
-  }
-}
-
-class StringArrayExpr extends ConstantExpr
-{
-  private final String[] value;
-
-  StringArrayExpr(String[] value)
-  {
-    this.value = Preconditions.checkNotNull(value, "value");
-  }
-
-  @Override
-  public Object getLiteralValue()
-  {
-    return value;
-  }
-
-  @Override
-  public String toString()
-  {
-    return Arrays.toString(value);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.ofStringArray(value);
-  }
-
-  @Override
-  public String stringify()
-  {
-    if (value.length == 0) {
-      return "<STRING>[]";
-    }
-
-    return StringUtils.format(
-        "<STRING>[%s]",
-        ARG_JOINER.join(
-            Arrays.stream(value)
-                  .map(s -> s == null
-                            ? NULL_LITERAL
-                            // escape as javascript string since string literals are wrapped in single quotes
-                            : StringUtils.format("'%s'", StringEscapeUtils.escapeJavaScript(s))
-                  )
-                  .iterator()
-        )
-    );
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    StringArrayExpr that = (StringArrayExpr) o;
-    return Arrays.equals(value, that.value);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Arrays.hashCode(value);
-  }
-}
-
-class DoubleExpr extends ConstantExpr
-{
-  private final Double value;
-
-  DoubleExpr(Double value)
-  {
-    this.value = Preconditions.checkNotNull(value, "value");
-  }
-
-  @Override
-  public Object getLiteralValue()
-  {
-    return value;
-  }
-
-  @Override
-  public String toString()
-  {
-    return String.valueOf(value);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.ofDouble(value);
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DoubleExpr that = (DoubleExpr) o;
-    return Objects.equals(value, that.value);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(value);
-  }
-}
-
-class NullDoubleExpr extends NullNumericConstantExpr
-{
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.ofDouble(null);
-  }
-
-  @Override
-  public final int hashCode()
-  {
-    return NullDoubleExpr.class.hashCode();
-  }
-
-  @Override
-  public final boolean equals(Object obj)
-  {
-    return obj instanceof NullDoubleExpr;
-  }
-}
-
-class DoubleArrayExpr extends ConstantExpr
-{
-  private final Double[] value;
-
-  DoubleArrayExpr(Double[] value)
-  {
-    this.value = Preconditions.checkNotNull(value, "value");
-  }
-
-  @Override
-  public Object getLiteralValue()
-  {
-    return value;
-  }
-
-  @Override
-  public String toString()
-  {
-    return Arrays.toString(value);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.ofDoubleArray(value);
-  }
-
-  @Override
-  public String stringify()
-  {
-    if (value.length == 0) {
-      return "<DOUBLE>[]";
-    }
-    return StringUtils.format("<DOUBLE>%s", toString());
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DoubleArrayExpr that = (DoubleArrayExpr) o;
-    return Arrays.equals(value, that.value);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Arrays.hashCode(value);
-  }
-}
-
-/**
- * This {@link Expr} node is used to represent a variable in the expression language. At evaluation time, the string
- * identifier will be used to retrieve the runtime value for the variable from {@link Expr.ObjectBinding}.
- * {@link IdentifierExpr} are terminal nodes of an expression tree, and have no children {@link Expr}.
- */
-class IdentifierExpr implements Expr
-{
-  private final String identifier;
-  private final String binding;
-
-  /**
-   * Construct a identifier expression for a {@link LambdaExpr}, where the {@link #identifier} is equal to
-   * {@link #binding}
-   */
-  IdentifierExpr(String value)
-  {
-    this.identifier = value;
-    this.binding = value;
-  }
-
-  /**
-   * Construct a normal identifier expression, where {@link #binding} is the key to fetch the backing value from
-   * {@link Expr.ObjectBinding} and the {@link #identifier} is a unique string that identifies this usage of the
-   * binding.
-   */
-  IdentifierExpr(String identifier, String binding)
-  {
-    this.identifier = identifier;
-    this.binding = binding;
-  }
-
-  @Override
-  public String toString()
-  {
-    return binding;
-  }
-
-  /**
-   * Unique identifier for the binding
-   */
-  @Nullable
-  public String getIdentifier()
-  {
-    return identifier;
-  }
-
-  /**
-   * Value binding, key to retrieve value from {@link Expr.ObjectBinding#get(String)}
-   */
-  @Nullable
-  public String getBinding()
-  {
-    return binding;
-  }
-
-  @Nullable
-  @Override
-  public String getIdentifierIfIdentifier()
-  {
-    return identifier;
-  }
-
-  @Nullable
-  @Override
-  public String getBindingIfIdentifier()
-  {
-    return binding;
-  }
-
-  @Nullable
-  @Override
-  public IdentifierExpr getIdentifierExprIfIdentifierExpr()
-  {
-    return this;
-  }
-
-  @Override
-  public BindingDetails analyzeInputs()
-  {
-    return new BindingDetails(this);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return ExprEval.bestEffortOf(bindings.get(binding));
-  }
-
-  @Override
-  public String stringify()
-  {
-    // escape as java strings since identifiers are wrapped in double quotes
-    return StringUtils.format("\"%s\"", StringEscapeUtils.escapeJava(binding));
-  }
-
-  @Override
-  public void visit(Visitor visitor)
-  {
-    visitor.visit(this);
-  }
-
-  @Override
-  public Expr visit(Shuttle shuttle)
-  {
-    return shuttle.visit(this);
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    IdentifierExpr that = (IdentifierExpr) o;
-    return Objects.equals(identifier, that.identifier);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(identifier);
-  }
-}
-
-class LambdaExpr implements Expr
-{
-  private final ImmutableList<IdentifierExpr> args;
-  private final Expr expr;
-
-  LambdaExpr(List<IdentifierExpr> args, Expr expr)
-  {
-    this.args = ImmutableList.copyOf(args);
-    this.expr = expr;
-  }
-
-  @Override
-  public String toString()
-  {
-    return StringUtils.format("(%s -> %s)", args, expr);
-  }
-
-  int identifierCount()
-  {
-    return args.size();
-  }
-
-  @Nullable
-  public String getIdentifier()
-  {
-    Preconditions.checkState(args.size() < 2, "LambdaExpr has multiple arguments");
-    if (args.size() == 1) {
-      return args.get(0).toString();
-    }
-    return null;
-  }
-
-  public List<String> getIdentifiers()
-  {
-    return args.stream().map(IdentifierExpr::toString).collect(Collectors.toList());
-  }
-
-  ImmutableList<IdentifierExpr> getIdentifierExprs()
-  {
-    return args;
-  }
-
-  public Expr getExpr()
-  {
-    return expr;
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return expr.eval(bindings);
-  }
-
-  @Override
-  public String stringify()
-  {
-    return StringUtils.format("(%s) -> %s", ARG_JOINER.join(getIdentifiers()), expr.stringify());
-  }
-
-  @Override
-  public void visit(Visitor visitor)
-  {
-    expr.visit(visitor);
-    visitor.visit(this);
-  }
-
-  @Override
-  public Expr visit(Shuttle shuttle)
-  {
-    List<IdentifierExpr> newArgs =
-        args.stream().map(arg -> (IdentifierExpr) shuttle.visit(arg)).collect(Collectors.toList());
-    Expr newBody = expr.visit(shuttle);
-    return shuttle.visit(new LambdaExpr(newArgs, newBody));
-  }
-
-  @Override
-  public BindingDetails analyzeInputs()
-  {
-    final Set<String> lambdaArgs = args.stream().map(IdentifierExpr::toString).collect(Collectors.toSet());
-    BindingDetails bodyDetails = expr.analyzeInputs();
-    return bodyDetails.removeLambdaArguments(lambdaArgs);
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    LambdaExpr that = (LambdaExpr) o;
-    return Objects.equals(args, that.args) &&
-           Objects.equals(expr, that.expr);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(args, expr);
-  }
-}
-
-/**
- * {@link Expr} node for a {@link Function} call. {@link FunctionExpr} has children {@link Expr} in the form of the
- * list of arguments that are passed to the {@link Function} along with the {@link Expr.ObjectBinding} when it is
- * evaluated.
- */
-class FunctionExpr implements Expr
-{
-  final Function function;
-  final ImmutableList<Expr> args;
-  private final String name;
-
-  FunctionExpr(Function function, String name, List<Expr> args)
-  {
-    this.function = function;
-    this.name = name;
-    this.args = ImmutableList.copyOf(args);
-    function.validateArguments(args);
-  }
-
-  @Override
-  public String toString()
-  {
-    return StringUtils.format("(%s %s)", name, args);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return function.apply(args, bindings);
-  }
-
-  @Override
-  public String stringify()
-  {
-    return StringUtils.format("%s(%s)", name, ARG_JOINER.join(args.stream().map(Expr::stringify).iterator()));
-  }
-
-  @Override
-  public void visit(Visitor visitor)
-  {
-    for (Expr child : args) {
-      child.visit(visitor);
-    }
-    visitor.visit(this);
-  }
-
-  @Override
-  public Expr visit(Shuttle shuttle)
-  {
-    List<Expr> newArgs = args.stream().map(shuttle::visit).collect(Collectors.toList());
-    return shuttle.visit(new FunctionExpr(function, name, newArgs));
-  }
-
-  @Override
-  public BindingDetails analyzeInputs()
-  {
-    BindingDetails accumulator = new BindingDetails();
-
-    for (Expr arg : args) {
-      accumulator = accumulator.with(arg);
-    }
-    return accumulator.withScalarArguments(function.getScalarInputs(args))
-                      .withArrayArguments(function.getArrayInputs(args))
-                      .withArrayInputs(function.hasArrayInputs())
-                      .withArrayOutput(function.hasArrayOutput());
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    FunctionExpr that = (FunctionExpr) o;
-    return args.equals(that.args) &&
-           name.equals(that.name);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(args, name);
-  }
-}
-
-/**
- * This {@link Expr} node is representative of an {@link ApplyFunction}, and has children in the form of a
- * {@link LambdaExpr} and the list of {@link Expr} arguments that are combined with {@link Expr.ObjectBinding} to
- * evaluate the {@link LambdaExpr}.
- */
-class ApplyFunctionExpr implements Expr
-{
-  final ApplyFunction function;
-  final String name;
-  final LambdaExpr lambdaExpr;
-  final ImmutableList<Expr> argsExpr;
-  final BindingDetails bindingDetails;
-  final BindingDetails lambdaBindingDetails;
-  final ImmutableList<BindingDetails> argsBindingDetails;
-
-  ApplyFunctionExpr(ApplyFunction function, String name, LambdaExpr expr, List<Expr> args)
-  {
-    this.function = function;
-    this.name = name;
-    this.argsExpr = ImmutableList.copyOf(args);
-    this.lambdaExpr = expr;
-
-    function.validateArguments(expr, args);
-
-    // apply function expressions are examined during expression selector creation, so precompute and cache the
-    // binding details of children
-    ImmutableList.Builder<BindingDetails> argBindingDetailsBuilder = ImmutableList.builder();
-    BindingDetails accumulator = new BindingDetails();
-    for (Expr arg : argsExpr) {
-      BindingDetails argDetails = arg.analyzeInputs();
-      argBindingDetailsBuilder.add(argDetails);
-      accumulator = accumulator.with(argDetails);
-    }
-
-    lambdaBindingDetails = lambdaExpr.analyzeInputs();
-
-    bindingDetails = accumulator.with(lambdaBindingDetails)
-                                .withArrayArguments(function.getArrayInputs(argsExpr))
-                                .withArrayInputs(true)
-                                .withArrayOutput(function.hasArrayOutput(lambdaExpr));
-    argsBindingDetails = argBindingDetailsBuilder.build();
-  }
-
-  @Override
-  public String toString()
-  {
-    return StringUtils.format("(%s %s, %s)", name, lambdaExpr, argsExpr);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    return function.apply(lambdaExpr, argsExpr, bindings);
-  }
-
-  @Override
-  public String stringify()
-  {
-    return StringUtils.format(
-        "%s(%s, %s)",
-        name,
-        lambdaExpr.stringify(),
-        ARG_JOINER.join(argsExpr.stream().map(Expr::stringify).iterator())
-    );
-  }
-
-  @Override
-  public void visit(Visitor visitor)
-  {
-    lambdaExpr.visit(visitor);
-    for (Expr arg : argsExpr) {
-      arg.visit(visitor);
-    }
-    visitor.visit(this);
-  }
-
-  @Override
-  public Expr visit(Shuttle shuttle)
-  {
-    LambdaExpr newLambda = (LambdaExpr) lambdaExpr.visit(shuttle);
-    List<Expr> newArgs = argsExpr.stream().map(shuttle::visit).collect(Collectors.toList());
-    return shuttle.visit(new ApplyFunctionExpr(function, name, newLambda, newArgs));
-  }
-
-  @Override
-  public BindingDetails analyzeInputs()
-  {
-    return bindingDetails;
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ApplyFunctionExpr that = (ApplyFunctionExpr) o;
-    return name.equals(that.name) &&
-           lambdaExpr.equals(that.lambdaExpr) &&
-           argsExpr.equals(that.argsExpr);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(name, lambdaExpr, argsExpr);
-  }
-}
-
-/**
- * Base type for all single argument operators, with a single {@link Expr} child for the operand.
- */
-abstract class UnaryExpr implements Expr
-{
-  final Expr expr;
-
-  UnaryExpr(Expr expr)
-  {
-    this.expr = expr;
-  }
-
-  abstract UnaryExpr copy(Expr expr);
-
-  @Override
-  public void visit(Visitor visitor)
-  {
-    expr.visit(visitor);
-    visitor.visit(this);
-  }
-
-  @Override
-  public Expr visit(Shuttle shuttle)
-  {
-    Expr newExpr = expr.visit(shuttle);
-    //noinspection ObjectEquality (checking for object equality here is intentional)
-    if (newExpr != expr) {
-      return shuttle.visit(copy(newExpr));
-    }
-    return shuttle.visit(this);
-  }
-
-  @Override
-  public BindingDetails analyzeInputs()
-  {
-    // currently all unary operators only operate on scalar inputs
-    return expr.analyzeInputs().withScalarArguments(ImmutableSet.of(expr));
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    UnaryExpr unaryExpr = (UnaryExpr) o;
-    return Objects.equals(expr, unaryExpr.expr);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(expr);
-  }
-}
-
-class UnaryMinusExpr extends UnaryExpr
-{
-  UnaryMinusExpr(Expr expr)
-  {
-    super(expr);
-  }
-
-  @Override
-  UnaryExpr copy(Expr expr)
-  {
-    return new UnaryMinusExpr(expr);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    ExprEval ret = expr.eval(bindings);
-    if (NullHandling.sqlCompatible() && (ret.value() == null)) {
-      return ExprEval.of(null);
-    }
-    if (ret.type() == ExprType.LONG) {
-      return ExprEval.of(-ret.asLong());
-    }
-    if (ret.type() == ExprType.DOUBLE) {
-      return ExprEval.of(-ret.asDouble());
-    }
-    throw new IAE("unsupported type " + ret.type());
-  }
-
-  @Override
-  public String stringify()
-  {
-    return StringUtils.format("-%s", expr.stringify());
-  }
-
-  @Override
-  public String toString()
-  {
-    return StringUtils.format("-%s", expr);
-  }
-}
-
-class UnaryNotExpr extends UnaryExpr
-{
-  UnaryNotExpr(Expr expr)
-  {
-    super(expr);
-  }
-
-  @Override
-  UnaryExpr copy(Expr expr)
-  {
-    return new UnaryNotExpr(expr);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    ExprEval ret = expr.eval(bindings);
-    if (NullHandling.sqlCompatible() && (ret.value() == null)) {
-      return ExprEval.of(null);
-    }
-    // conforming to other boolean-returning binary operators
-    ExprType retType = ret.type() == ExprType.DOUBLE ? ExprType.DOUBLE : ExprType.LONG;
-    return ExprEval.of(!ret.asBoolean(), retType);
-  }
-
-  @Override
-  public String stringify()
-  {
-    return StringUtils.format("!%s", expr.stringify());
-  }
-
-  @Override
-  public String toString()
-  {
-    return StringUtils.format("!%s", expr);
-  }
-}
-
-/**
- * Base type for all binary operators, this {@link Expr} has two children {@link Expr} for the left and right side
- * operands.
- *
- * Note: all concrete subclass of this should have constructor with the form of <init>(String, Expr, Expr)
- * if it's not possible, just be sure Evals.binaryOp() can handle that
- */
-abstract class BinaryOpExprBase implements Expr
-{
-  protected final String op;
-  protected final Expr left;
-  protected final Expr right;
-
-  BinaryOpExprBase(String op, Expr left, Expr right)
-  {
-    this.op = op;
-    this.left = left;
-    this.right = right;
-  }
-
-  @Override
-  public void visit(Visitor visitor)
-  {
-    left.visit(visitor);
-    right.visit(visitor);
-    visitor.visit(this);
-  }
-
-  @Override
-  public Expr visit(Shuttle shuttle)
-  {
-    Expr newLeft = left.visit(shuttle);
-    Expr newRight = right.visit(shuttle);
-    //noinspection ObjectEquality (checking for object equality here is intentional)
-    if (left != newLeft || right != newRight) {
-      return shuttle.visit(copy(newLeft, newRight));
-    }
-    return shuttle.visit(this);
-  }
-
-  @Override
-  public String toString()
-  {
-    return StringUtils.format("(%s %s %s)", op, left, right);
-  }
-
-  @Override
-  public String stringify()
-  {
-    return StringUtils.format("(%s %s %s)", left.stringify(), op, right.stringify());
-  }
-
-  protected abstract BinaryOpExprBase copy(Expr left, Expr right);
-
-  @Override
-  public BindingDetails analyzeInputs()
-  {
-    // currently all binary operators operate on scalar inputs
-    return left.analyzeInputs().with(right).withScalarArguments(ImmutableSet.of(left, right));
-  }
-
-  @Override
-  public boolean equals(Object o)
-  {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    BinaryOpExprBase that = (BinaryOpExprBase) o;
-    return Objects.equals(op, that.op) &&
-           Objects.equals(left, that.left) &&
-           Objects.equals(right, that.right);
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return Objects.hash(op, left, right);
-  }
-}
-
-/**
- * Base class for numerical binary operators, with additional methods defined to evaluate primitive values directly
- * instead of wrapped with {@link ExprEval}
- */
-abstract class BinaryEvalOpExprBase extends BinaryOpExprBase
-{
-  BinaryEvalOpExprBase(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    ExprEval leftVal = left.eval(bindings);
-    ExprEval rightVal = right.eval(bindings);
-
-    // Result of any Binary expressions is null if any of the argument is null.
-    // e.g "select null * 2 as c;" or "select null + 1 as c;" will return null as per Standard SQL spec.
-    if (NullHandling.sqlCompatible() && (leftVal.value() == null || rightVal.value() == null)) {
-      return ExprEval.of(null);
-    }
-
-    if (leftVal.type() == ExprType.STRING && rightVal.type() == ExprType.STRING) {
-      return evalString(leftVal.asString(), rightVal.asString());
-    } else if (leftVal.type() == ExprType.LONG && rightVal.type() == ExprType.LONG) {
-      if (NullHandling.sqlCompatible() && (leftVal.isNumericNull() || rightVal.isNumericNull())) {
-        return ExprEval.of(null);
-      }
-      return ExprEval.of(evalLong(leftVal.asLong(), rightVal.asLong()));
-    } else {
-      if (NullHandling.sqlCompatible() && (leftVal.isNumericNull() || rightVal.isNumericNull())) {
-        return ExprEval.of(null);
-      }
-      return ExprEval.of(evalDouble(leftVal.asDouble(), rightVal.asDouble()));
-    }
-  }
-
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    throw new IllegalArgumentException("unsupported type " + ExprType.STRING);
-  }
-
-  protected abstract long evalLong(long left, long right);
-
-  protected abstract double evalDouble(double left, double right);
-}
-
-class BinMinusExpr extends BinaryEvalOpExprBase
-{
-  BinMinusExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinMinusExpr(op, left, right);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return left - right;
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return left - right;
-  }
-}
-
-class BinPowExpr extends BinaryEvalOpExprBase
-{
-  BinPowExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinPowExpr(op, left, right);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return LongMath.pow(left, Ints.checkedCast(right));
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return Math.pow(left, right);
-  }
-}
-
-class BinMulExpr extends BinaryEvalOpExprBase
-{
-  BinMulExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinMulExpr(op, left, right);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return left * right;
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return left * right;
-  }
-}
-
-class BinDivExpr extends BinaryEvalOpExprBase
-{
-  BinDivExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinDivExpr(op, left, right);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return left / right;
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return left / right;
-  }
-}
-
-class BinModuloExpr extends BinaryEvalOpExprBase
-{
-  BinModuloExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinModuloExpr(op, left, right);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return left % right;
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return left % right;
-  }
-}
-
-class BinPlusExpr extends BinaryEvalOpExprBase
-{
-  BinPlusExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinPlusExpr(op, left, right);
-  }
-
-  @Override
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    return ExprEval.of(NullHandling.nullToEmptyIfNeeded(left)
-                       + NullHandling.nullToEmptyIfNeeded(right));
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return left + right;
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return left + right;
-  }
-}
-
-class BinLtExpr extends BinaryEvalOpExprBase
-{
-  BinLtExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinLtExpr(op, left, right);
-  }
-
-  @Override
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) < 0, ExprType.LONG);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return Evals.asLong(left < right);
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    // Use Double.compare for more consistent NaN handling.
-    return Evals.asDouble(Double.compare(left, right) < 0);
-  }
-}
-
-class BinLeqExpr extends BinaryEvalOpExprBase
-{
-  BinLeqExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinLeqExpr(op, left, right);
-  }
-
-  @Override
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) <= 0, ExprType.LONG);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return Evals.asLong(left <= right);
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    // Use Double.compare for more consistent NaN handling.
-    return Evals.asDouble(Double.compare(left, right) <= 0);
-  }
-}
-
-class BinGtExpr extends BinaryEvalOpExprBase
-{
-  BinGtExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinGtExpr(op, left, right);
-  }
-
-  @Override
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) > 0, ExprType.LONG);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return Evals.asLong(left > right);
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    // Use Double.compare for more consistent NaN handling.
-    return Evals.asDouble(Double.compare(left, right) > 0);
-  }
-}
-
-class BinGeqExpr extends BinaryEvalOpExprBase
-{
-  BinGeqExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinGeqExpr(op, left, right);
-  }
-
-  @Override
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    return ExprEval.of(Comparators.<String>naturalNullsFirst().compare(left, right) >= 0, ExprType.LONG);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return Evals.asLong(left >= right);
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    // Use Double.compare for more consistent NaN handling.
-    return Evals.asDouble(Double.compare(left, right) >= 0);
-  }
-}
-
-class BinEqExpr extends BinaryEvalOpExprBase
-{
-  BinEqExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinEqExpr(op, left, right);
-  }
-
-  @Override
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    return ExprEval.of(Objects.equals(left, right), ExprType.LONG);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return Evals.asLong(left == right);
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return Evals.asDouble(left == right);
-  }
-}
-
-class BinNeqExpr extends BinaryEvalOpExprBase
-{
-  BinNeqExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinNeqExpr(op, left, right);
-  }
-
-  @Override
-  protected ExprEval evalString(@Nullable String left, @Nullable String right)
-  {
-    return ExprEval.of(!Objects.equals(left, right), ExprType.LONG);
-  }
-
-  @Override
-  protected final long evalLong(long left, long right)
-  {
-    return Evals.asLong(left != right);
-  }
-
-  @Override
-  protected final double evalDouble(double left, double right)
-  {
-    return Evals.asDouble(left != right);
-  }
-}
-
-class BinAndExpr extends BinaryOpExprBase
-{
-  BinAndExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinAndExpr(op, left, right);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    ExprEval leftVal = left.eval(bindings);
-    return leftVal.asBoolean() ? right.eval(bindings) : leftVal;
-  }
-}
-
-class BinOrExpr extends BinaryOpExprBase
-{
-  BinOrExpr(String op, Expr left, Expr right)
-  {
-    super(op, left, right);
-  }
-
-  @Override
-  protected BinaryOpExprBase copy(Expr left, Expr right)
-  {
-    return new BinOrExpr(op, left, right);
-  }
-
-  @Override
-  public ExprEval eval(ObjectBinding bindings)
-  {
-    ExprEval leftVal = left.eval(bindings);
-    return leftVal.asBoolean() ? leftVal : right.eval(bindings);
-  }
-
-}
-
diff --git a/core/src/main/java/org/apache/druid/math/expr/FunctionalExpr.java b/core/src/main/java/org/apache/druid/math/expr/FunctionalExpr.java
new file mode 100644
index 0000000..2b3474a
--- /dev/null
+++ b/core/src/main/java/org/apache/druid/math/expr/FunctionalExpr.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.math.expr;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import org.apache.druid.java.util.common.StringUtils;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+class LambdaExpr implements Expr
+{
+  private final ImmutableList<IdentifierExpr> args;
+  private final Expr expr;
+
+  LambdaExpr(List<IdentifierExpr> args, Expr expr)
+  {
+    this.args = ImmutableList.copyOf(args);
+    this.expr = expr;
+  }
+
+  @Override
+  public String toString()
+  {
+    return StringUtils.format("(%s -> %s)", args, expr);
+  }
+
+  int identifierCount()
+  {
+    return args.size();
+  }
+
+  @Nullable
+  public String getIdentifier()
+  {
+    Preconditions.checkState(args.size() < 2, "LambdaExpr has multiple arguments");
+    if (args.size() == 1) {
+      return args.get(0).toString();
+    }
+    return null;
+  }
+
+  public List<String> getIdentifiers()
+  {
+    return args.stream().map(IdentifierExpr::toString).collect(Collectors.toList());
+  }
+
+  ImmutableList<IdentifierExpr> getIdentifierExprs()
+  {
+    return args;
+  }
+
+  public Expr getExpr()
+  {
+    return expr;
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return expr.eval(bindings);
+  }
+
+  @Override
+  public String stringify()
+  {
+    return StringUtils.format("(%s) -> %s", ARG_JOINER.join(getIdentifiers()), expr.stringify());
+  }
+
+  @Override
+  public void visit(Visitor visitor)
+  {
+    expr.visit(visitor);
+    visitor.visit(this);
+  }
+
+  @Override
+  public Expr visit(Shuttle shuttle)
+  {
+    List<IdentifierExpr> newArgs =
+        args.stream().map(arg -> (IdentifierExpr) shuttle.visit(arg)).collect(Collectors.toList());
+    Expr newBody = expr.visit(shuttle);
+    return shuttle.visit(new LambdaExpr(newArgs, newBody));
+  }
+
+  @Override
+  public BindingDetails analyzeInputs()
+  {
+    final Set<String> lambdaArgs = args.stream().map(IdentifierExpr::toString).collect(Collectors.toSet());
+    BindingDetails bodyDetails = expr.analyzeInputs();
+    return bodyDetails.removeLambdaArguments(lambdaArgs);
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    LambdaExpr that = (LambdaExpr) o;
+    return Objects.equals(args, that.args) &&
+           Objects.equals(expr, that.expr);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(args, expr);
+  }
+}
+
+/**
+ * {@link Expr} node for a {@link Function} call. {@link FunctionExpr} has children {@link Expr} in the form of the
+ * list of arguments that are passed to the {@link Function} along with the {@link Expr.ObjectBinding} when it is
+ * evaluated.
+ */
+class FunctionExpr implements Expr
+{
+  final Function function;
+  final ImmutableList<Expr> args;
+  private final String name;
+
+  FunctionExpr(Function function, String name, List<Expr> args)
+  {
+    this.function = function;
+    this.name = name;
+    this.args = ImmutableList.copyOf(args);
+    function.validateArguments(args);
+  }
+
+  @Override
+  public String toString()
+  {
+    return StringUtils.format("(%s %s)", name, args);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return function.apply(args, bindings);
+  }
+
+  @Override
+  public String stringify()
+  {
+    return StringUtils.format("%s(%s)", name, ARG_JOINER.join(args.stream().map(Expr::stringify).iterator()));
+  }
+
+  @Override
+  public void visit(Visitor visitor)
+  {
+    for (Expr child : args) {
+      child.visit(visitor);
+    }
+    visitor.visit(this);
+  }
+
+  @Override
+  public Expr visit(Shuttle shuttle)
+  {
+    List<Expr> newArgs = args.stream().map(shuttle::visit).collect(Collectors.toList());
+    return shuttle.visit(new FunctionExpr(function, name, newArgs));
+  }
+
+  @Override
+  public BindingDetails analyzeInputs()
+  {
+    BindingDetails accumulator = new BindingDetails();
+
+    for (Expr arg : args) {
+      accumulator = accumulator.with(arg);
+    }
+    return accumulator.withScalarArguments(function.getScalarInputs(args))
+                      .withArrayArguments(function.getArrayInputs(args))
+                      .withArrayInputs(function.hasArrayInputs())
+                      .withArrayOutput(function.hasArrayOutput());
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    FunctionExpr that = (FunctionExpr) o;
+    return args.equals(that.args) &&
+           name.equals(that.name);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(args, name);
+  }
+}
+
+/**
+ * This {@link Expr} node is representative of an {@link ApplyFunction}, and has children in the form of a
+ * {@link LambdaExpr} and the list of {@link Expr} arguments that are combined with {@link Expr.ObjectBinding} to
+ * evaluate the {@link LambdaExpr}.
+ */
+class ApplyFunctionExpr implements Expr
+{
+  final ApplyFunction function;
+  final String name;
+  final LambdaExpr lambdaExpr;
+  final ImmutableList<Expr> argsExpr;
+  final BindingDetails bindingDetails;
+  final BindingDetails lambdaBindingDetails;
+  final ImmutableList<BindingDetails> argsBindingDetails;
+
+  ApplyFunctionExpr(ApplyFunction function, String name, LambdaExpr expr, List<Expr> args)
+  {
+    this.function = function;
+    this.name = name;
+    this.argsExpr = ImmutableList.copyOf(args);
+    this.lambdaExpr = expr;
+
+    function.validateArguments(expr, args);
+
+    // apply function expressions are examined during expression selector creation, so precompute and cache the
+    // binding details of children
+    ImmutableList.Builder<BindingDetails> argBindingDetailsBuilder = ImmutableList.builder();
+    BindingDetails accumulator = new BindingDetails();
+    for (Expr arg : argsExpr) {
+      BindingDetails argDetails = arg.analyzeInputs();
+      argBindingDetailsBuilder.add(argDetails);
+      accumulator = accumulator.with(argDetails);
+    }
+
+    lambdaBindingDetails = lambdaExpr.analyzeInputs();
+
+    bindingDetails = accumulator.with(lambdaBindingDetails)
+                                .withArrayArguments(function.getArrayInputs(argsExpr))
+                                .withArrayInputs(true)
+                                .withArrayOutput(function.hasArrayOutput(lambdaExpr));
+    argsBindingDetails = argBindingDetailsBuilder.build();
+  }
+
+  @Override
+  public String toString()
+  {
+    return StringUtils.format("(%s %s, %s)", name, lambdaExpr, argsExpr);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return function.apply(lambdaExpr, argsExpr, bindings);
+  }
+
+  @Override
+  public String stringify()
+  {
+    return StringUtils.format(
+        "%s(%s, %s)",
+        name,
+        lambdaExpr.stringify(),
+        ARG_JOINER.join(argsExpr.stream().map(Expr::stringify).iterator())
+    );
+  }
+
+  @Override
+  public void visit(Visitor visitor)
+  {
+    lambdaExpr.visit(visitor);
+    for (Expr arg : argsExpr) {
+      arg.visit(visitor);
+    }
+    visitor.visit(this);
+  }
+
+  @Override
+  public Expr visit(Shuttle shuttle)
+  {
+    LambdaExpr newLambda = (LambdaExpr) lambdaExpr.visit(shuttle);
+    List<Expr> newArgs = argsExpr.stream().map(shuttle::visit).collect(Collectors.toList());
+    return shuttle.visit(new ApplyFunctionExpr(function, name, newLambda, newArgs));
+  }
+
+  @Override
+  public BindingDetails analyzeInputs()
+  {
+    return bindingDetails;
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    ApplyFunctionExpr that = (ApplyFunctionExpr) o;
+    return name.equals(that.name) &&
+           lambdaExpr.equals(that.lambdaExpr) &&
+           argsExpr.equals(that.argsExpr);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(name, lambdaExpr, argsExpr);
+  }
+}
diff --git a/core/src/main/java/org/apache/druid/math/expr/IdentifierExpr.java b/core/src/main/java/org/apache/druid/math/expr/IdentifierExpr.java
new file mode 100644
index 0000000..d23657a
--- /dev/null
+++ b/core/src/main/java/org/apache/druid/math/expr/IdentifierExpr.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.math.expr;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.druid.java.util.common.StringUtils;
+
+import javax.annotation.Nullable;
+import java.util.Objects;
+
+/**
+ * This {@link Expr} node is used to represent a variable in the expression language. At evaluation time, the string
+ * identifier will be used to retrieve the runtime value for the variable from {@link Expr.ObjectBinding}.
+ * {@link IdentifierExpr} are terminal nodes of an expression tree, and have no children {@link Expr}.
+ */
+class IdentifierExpr implements Expr
+{
+  private final String identifier;
+  private final String binding;
+
+  /**
+   * Construct a identifier expression for a {@link LambdaExpr}, where the {@link #identifier} is equal to
+   * {@link #binding}
+   */
+  IdentifierExpr(String value)
+  {
+    this.identifier = value;
+    this.binding = value;
+  }
+
+  /**
+   * Construct a normal identifier expression, where {@link #binding} is the key to fetch the backing value from
+   * {@link Expr.ObjectBinding} and the {@link #identifier} is a unique string that identifies this usage of the
+   * binding.
+   */
+  IdentifierExpr(String identifier, String binding)
+  {
+    this.identifier = identifier;
+    this.binding = binding;
+  }
+
+  @Override
+  public String toString()
+  {
+    return binding;
+  }
+
+  /**
+   * Unique identifier for the binding
+   */
+  @Nullable
+  public String getIdentifier()
+  {
+    return identifier;
+  }
+
+  /**
+   * Value binding, key to retrieve value from {@link Expr.ObjectBinding#get(String)}
+   */
+  @Nullable
+  public String getBinding()
+  {
+    return binding;
+  }
+
+  @Nullable
+  @Override
+  public String getIdentifierIfIdentifier()
+  {
+    return identifier;
+  }
+
+  @Nullable
+  @Override
+  public String getBindingIfIdentifier()
+  {
+    return binding;
+  }
+
+  @Nullable
+  @Override
+  public IdentifierExpr getIdentifierExprIfIdentifierExpr()
+  {
+    return this;
+  }
+
+  @Override
+  public BindingDetails analyzeInputs()
+  {
+    return new BindingDetails(this);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    return ExprEval.bestEffortOf(bindings.get(binding));
+  }
+
+  @Override
+  public String stringify()
+  {
+    // escape as java strings since identifiers are wrapped in double quotes
+    return StringUtils.format("\"%s\"", StringEscapeUtils.escapeJava(binding));
+  }
+
+  @Override
+  public void visit(Visitor visitor)
+  {
+    visitor.visit(this);
+  }
+
+  @Override
+  public Expr visit(Shuttle shuttle)
+  {
+    return shuttle.visit(this);
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    IdentifierExpr that = (IdentifierExpr) o;
+    return Objects.equals(identifier, that.identifier);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(identifier);
+  }
+}
diff --git a/core/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java b/core/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java
new file mode 100644
index 0000000..5a41e90
--- /dev/null
+++ b/core/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.math.expr;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.druid.common.config.NullHandling;
+import org.apache.druid.java.util.common.IAE;
+import org.apache.druid.java.util.common.StringUtils;
+
+import java.util.Objects;
+
+/**
+ * Base type for all single argument operators, with a single {@link Expr} child for the operand.
+ */
+abstract class UnaryExpr implements Expr
+{
+  final Expr expr;
+
+  UnaryExpr(Expr expr)
+  {
+    this.expr = expr;
+  }
+
+  abstract UnaryExpr copy(Expr expr);
+
+  @Override
+  public void visit(Visitor visitor)
+  {
+    expr.visit(visitor);
+    visitor.visit(this);
+  }
+
+  @Override
+  public Expr visit(Shuttle shuttle)
+  {
+    Expr newExpr = expr.visit(shuttle);
+    //noinspection ObjectEquality (checking for object equality here is intentional)
+    if (newExpr != expr) {
+      return shuttle.visit(copy(newExpr));
+    }
+    return shuttle.visit(this);
+  }
+
+  @Override
+  public BindingDetails analyzeInputs()
+  {
+    // currently all unary operators only operate on scalar inputs
+    return expr.analyzeInputs().withScalarArguments(ImmutableSet.of(expr));
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    UnaryExpr unaryExpr = (UnaryExpr) o;
+    return Objects.equals(expr, unaryExpr.expr);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(expr);
+  }
+}
+
+class UnaryMinusExpr extends UnaryExpr
+{
+  UnaryMinusExpr(Expr expr)
+  {
+    super(expr);
+  }
+
+  @Override
+  UnaryExpr copy(Expr expr)
+  {
+    return new UnaryMinusExpr(expr);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    ExprEval ret = expr.eval(bindings);
+    if (NullHandling.sqlCompatible() && (ret.value() == null)) {
+      return ExprEval.of(null);
+    }
+    if (ret.type() == ExprType.LONG) {
+      return ExprEval.of(-ret.asLong());
+    }
+    if (ret.type() == ExprType.DOUBLE) {
+      return ExprEval.of(-ret.asDouble());
+    }
+    throw new IAE("unsupported type " + ret.type());
+  }
+
+  @Override
+  public String stringify()
+  {
+    return StringUtils.format("-%s", expr.stringify());
+  }
+
+  @Override
+  public String toString()
+  {
+    return StringUtils.format("-%s", expr);
+  }
+}
+
+class UnaryNotExpr extends UnaryExpr
+{
+  UnaryNotExpr(Expr expr)
+  {
+    super(expr);
+  }
+
+  @Override
+  UnaryExpr copy(Expr expr)
+  {
+    return new UnaryNotExpr(expr);
+  }
+
+  @Override
+  public ExprEval eval(ObjectBinding bindings)
+  {
+    ExprEval ret = expr.eval(bindings);
+    if (NullHandling.sqlCompatible() && (ret.value() == null)) {
+      return ExprEval.of(null);
+    }
+    // conforming to other boolean-returning binary operators
+    ExprType retType = ret.type() == ExprType.DOUBLE ? ExprType.DOUBLE : ExprType.LONG;
+    return ExprEval.of(!ret.asBoolean(), retType);
+  }
+
+  @Override
+  public String stringify()
+  {
+    return StringUtils.format("!%s", expr.stringify());
+  }
+
+  @Override
+  public String toString()
+  {
+    return StringUtils.format("!%s", expr);
+  }
+}
