@Override
  public SelType call(String methodName, SelType[] args) {
    if ("min".equals(methodName) && args.length == 2) {
      return SelLong.of(Math.min(((SelLong) args[0]).longVal(), ((SelLong) args[1]).longVal()));
    } else if ("max".equals(methodName) && args.length == 2) {
      return SelLong.of(Math.max(((SelLong) args[0]).longVal(), ((SelLong) args[1]).longVal()));
    } else if ("random".equals(methodName) && args.length == 0) {
      return SelDouble.of(Math.random());
    } else if ("pow".equals(methodName) && args.length == 2) {
      return SelDouble.of(
          Math.pow(
              ((Number) args[0].getInternalVal()).doubleValue(),
              ((Number) args[1].getInternalVal()).doubleValue()));
    }
    throw new UnsupportedOperationException(
        type()
            + " DO NOT support calling method: "
            + methodName
            + " with args: "
            + Arrays.toString(args));
  }
@Test
  public void call() {
    SelType res = SelJavaMath.INSTANCE.call("min", new SelType[] {SelLong.of(1), SelLong.of(2)});
    assertEquals("LONG: 1", res.type() + ": " + res);
    res = SelJavaMath.INSTANCE.call("max", new SelType[] {SelLong.of(1), SelLong.of(2)});
    assertEquals("LONG: 2", res.type() + ": " + res);
    res = SelJavaMath.INSTANCE.call("pow", new SelType[] {SelLong.of(3), SelLong.of(2)});
    assertEquals(SelTypes.DOUBLE, res.type());
    assertEquals(9.0, ((SelDouble) res).doubleVal(), 0.01);
    res = SelJavaMath.INSTANCE.call("random", new SelType[] {});
    assertEquals(SelTypes.DOUBLE, res.type());
  }