Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Support mathematical functions: conv, crc32, mod, pow/power, round, sign, sqrt, truncate #577

Merged
merged 14 commits into from
Jul 20, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ public FunctionExpression ceiling(Expression... expressions) {
return function(BuiltinFunctionName.CEILING, expressions);
}

public FunctionExpression conv(Expression... expressions) {
return function(BuiltinFunctionName.CONV, expressions);
}

public FunctionExpression crc32(Expression... expressions) {
return function(BuiltinFunctionName.CRC32, expressions);
}

public FunctionExpression exp(Expression... expressions) {
return function(BuiltinFunctionName.EXP, expressions);
}
Expand All @@ -97,6 +105,34 @@ public FunctionExpression log2(Expression... expressions) {
return function(BuiltinFunctionName.LOG2, expressions);
}

public FunctionExpression mod(Expression... expressions) {
return function(BuiltinFunctionName.MOD, expressions);
}

public FunctionExpression pow(Expression... expressions) {
return function(BuiltinFunctionName.POW, expressions);
}

public FunctionExpression power(Expression... expressions) {
return function(BuiltinFunctionName.POWER, expressions);
}

public FunctionExpression round(Expression... expressions) {
return function(BuiltinFunctionName.ROUND, expressions);
}

public FunctionExpression sign(Expression... expressions) {
return function(BuiltinFunctionName.SIGN, expressions);
}

public FunctionExpression sqrt(Expression... expressions) {
return function(BuiltinFunctionName.SQRT, expressions);
}

public FunctionExpression truncate(Expression... expressions) {
return function(BuiltinFunctionName.TRUNCATE, expressions);
}

public FunctionExpression add(Expression... expressions) {
return function(BuiltinFunctionName.ADD, expressions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ public enum BuiltinFunctionName {
ABS(FunctionName.of("abs")),
CEIL(FunctionName.of("ceil")),
CEILING(FunctionName.of("ceiling")),
CONV(FunctionName.of("conv")),
CRC32(FunctionName.of("crc32")),
EXP(FunctionName.of("exp")),
FLOOR(FunctionName.of("floor")),
LN(FunctionName.of("ln")),
LOG(FunctionName.of("log")),
LOG10(FunctionName.of("log10")),
LOG2(FunctionName.of("log2")),
MOD(FunctionName.of("mod")),
POW(FunctionName.of("pow")),
POWER(FunctionName.of("power")),
ROUND(FunctionName.of("round")),
SIGN(FunctionName.of("sign")),
SQRT(FunctionName.of("sqrt")),
TRUNCATE(FunctionName.of("truncate")),

/**
* Text Functions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,60 @@

@UtilityClass
public class OperatorUtils {
/**
* Construct {@link FunctionBuilder} which call function with three arguments produced by
* observers.In general, if any operand evaluates to a MISSING value, the enclosing operator
* will return MISSING; if none of operands evaluates to a MISSING value but there is an
* operand evaluates to a NULL value, the enclosing operator will return NULL.
*
* @param functionName function name
* @param function {@link BiFunction}
* @param observer1 extract the value of type T from the first argument
* @param observer2 extract the value of type U from the first argument
* @param observer3 extract the value of type V from the first argument
* @param returnType return type
* @param <T> the type of the first argument to the function
* @param <U> the type of the second argument to the function
* @param <V> the type of the third argument to the function
* @param <R> the type of the result of the function
* @return {@link FunctionBuilder}
*/
public static <T, U, V, R> FunctionBuilder tripleArgFunc(
FunctionName functionName,
TriFunction<T, U, V, R> function,
Function<ExprValue, T> observer1,
Function<ExprValue, U> observer2,
Function<ExprValue, V> observer3,
ExprCoreType returnType) {
return arguments -> new FunctionExpression(functionName, arguments) {
@Override
public ExprValue valueOf(Environment<Expression, ExprValue> valueEnv) {
ExprValue arg1 = arguments.get(0).valueOf(valueEnv);
ExprValue arg2 = arguments.get(1).valueOf(valueEnv);
ExprValue arg3 = arguments.get(2).valueOf(valueEnv);
if (arg1.isMissing() || arg2.isMissing() || arg3.isMissing()) {
return ExprValueUtils.missingValue();
} else if (arg1.isNull() || arg2.isNull() || arg3.isNull()) {
return ExprValueUtils.nullValue();
} else {
return ExprValueUtils.fromObjectValue(
function.apply(observer1.apply(arg1), observer2.apply(arg2), observer3.apply(arg3)));
}
}

@Override
public ExprType type() {
return returnType;
}

@Override
public String toString() {
return String.format("%s(%s, %s, %s)", functionName, arguments.get(0).toString(), arguments
.get(1).toString(), arguments.get(2).toString());
}
};
}

/**
* Construct {@link FunctionBuilder} which call function with arguments produced by observer.
*
Expand Down Expand Up @@ -222,4 +276,8 @@ public String toString() {
*/
public static final BiPredicate<ExprValue, ExprValue> COMPARE_WITH_NULL_OR_MISSING =
(left, right) -> left.isMissing() || right.isMissing() || left.isNull() || right.isNull();

public interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ private static FunctionResolver divide() {
return new FunctionResolver(
BuiltinFunctionName.DIVIDE.getName(),
scalarFunction(BuiltinFunctionName.DIVIDE.getName(),
(v1, v2) -> v1 / v2,
(v1, v2) -> v1 / v2,
(v1, v2) -> v1 / v2,
(v1, v2) -> v1 / v2)
(v1, v2) -> v2 == 0 ? null : v1 / v2,
(v1, v2) -> v2 == 0 ? null : v1 / v2,
(v1, v2) -> v2 == 0 ? null : v1 / v2,
(v1, v2) -> v2 == 0 ? null : v1 / v2)
);
}

Expand All @@ -106,10 +106,10 @@ private static FunctionResolver modules() {
return new FunctionResolver(
BuiltinFunctionName.MODULES.getName(),
scalarFunction(BuiltinFunctionName.MODULES.getName(),
(v1, v2) -> v1 % v2,
(v1, v2) -> v1 % v2,
(v1, v2) -> v1 % v2,
(v1, v2) -> v1 % v2)
(v1, v2) -> v2 == 0 ? null : v1 % v2,
(v1, v2) -> v2 == 0 ? null : v1 % v2,
(v1, v2) -> v2 == 0 ? null : v1 % v2,
(v1, v2) -> v2 == 0 ? null : v1 % v2)
);
}

Expand Down
Loading