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

Support mathematical functions ceil/ceiling, exp, floor, ln, log #540

Merged
merged 16 commits into from
Jul 12, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import com.amazon.opendistroforelasticsearch.sql.data.model.ExprValueUtils;
import com.amazon.opendistroforelasticsearch.sql.data.type.ExprType;
import com.amazon.opendistroforelasticsearch.sql.expression.aggregation.Aggregator;
import com.amazon.opendistroforelasticsearch.sql.expression.env.Environment;
import com.amazon.opendistroforelasticsearch.sql.expression.function.BuiltinFunctionName;
import com.amazon.opendistroforelasticsearch.sql.expression.function.BuiltinFunctionRepository;
import com.amazon.opendistroforelasticsearch.sql.expression.function.FunctionName;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;

Expand Down Expand Up @@ -62,102 +62,124 @@ public static ReferenceExpression ref(String ref, ExprType type) {
}

public FunctionExpression abs(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.ABS.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.ABS, expressions);
}

public FunctionExpression ceil(Expression... expressions) {
return function(BuiltinFunctionName.CEIL, expressions);
}

public FunctionExpression ceiling(Expression... expressions) {
return function(BuiltinFunctionName.CEILING, expressions);
}

public FunctionExpression exp(Expression... expressions) {
return function(BuiltinFunctionName.EXP, expressions);
}

public FunctionExpression floor(Expression... expressions) {
return function(BuiltinFunctionName.FLOOR, expressions);
}

public FunctionExpression ln(Expression... expressions) {
return function(BuiltinFunctionName.LN, expressions);
}

public FunctionExpression log(Expression... expressions) {
return function(BuiltinFunctionName.LOG, expressions);
}

public FunctionExpression log10(Expression... expressions) {
return function(BuiltinFunctionName.LOG10, expressions);
}

public FunctionExpression log2(Expression... expressions) {
return function(BuiltinFunctionName.LOG2, expressions);
}

public FunctionExpression add(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.ADD.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.ADD, expressions);
}

public FunctionExpression subtract(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.SUBTRACT.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.SUBTRACT, expressions);
}

public FunctionExpression multiply(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.MULTIPLY.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.MULTIPLY, expressions);
}

public FunctionExpression divide(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.DIVIDE.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.DIVIDE, expressions);
}

public FunctionExpression module(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.MODULES.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.MODULES, expressions);
}

public FunctionExpression and(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.AND.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.AND, expressions);
}

public FunctionExpression or(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.OR.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.OR, expressions);
}

public FunctionExpression xor(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.XOR.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.XOR, expressions);
}

public FunctionExpression not(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.NOT.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.NOT, expressions);
}

public FunctionExpression equal(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.EQUAL.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.EQUAL, expressions);
}

public FunctionExpression notequal(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.NOTEQUAL.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.NOTEQUAL, expressions);
}

public FunctionExpression less(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.LESS.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.LESS, expressions);
}

public FunctionExpression lte(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.LTE.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.LTE, expressions);
}

public FunctionExpression greater(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.GREATER.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.GREATER, expressions);
}

public FunctionExpression gte(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.GTE.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.GTE, expressions);
}

public FunctionExpression like(Expression... expressions) {
return (FunctionExpression)
repository.compile(BuiltinFunctionName.LIKE.getName(), Arrays.asList(expressions));
return function(BuiltinFunctionName.LIKE, expressions);
}

public Aggregator avg(Expression... expressions) {
return (Aggregator)
repository.compile(BuiltinFunctionName.AVG.getName(), Arrays.asList(expressions));
return aggregate(BuiltinFunctionName.AVG, expressions);
}

public Aggregator sum(Expression... expressions) {
return (Aggregator)
repository.compile(BuiltinFunctionName.SUM.getName(), Arrays.asList(expressions));
return aggregate(BuiltinFunctionName.SUM, expressions);
}

public Aggregator count(Expression... expressions) {
return (Aggregator)
repository.compile(BuiltinFunctionName.COUNT.getName(), Arrays.asList(expressions));
return aggregate(BuiltinFunctionName.COUNT, expressions);
}

private FunctionExpression function(BuiltinFunctionName functionName, Expression... expressions) {
return (FunctionExpression) repository.compile(
functionName.getName(), Arrays.asList(expressions));
}

private Aggregator aggregate(BuiltinFunctionName functionName, Expression... expressions) {
return (Aggregator) repository.compile(
functionName.getName(), Arrays.asList(expressions));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.amazon.opendistroforelasticsearch.sql.expression.aggregation.AggregatorFunction;
import com.amazon.opendistroforelasticsearch.sql.expression.function.BuiltinFunctionRepository;
import com.amazon.opendistroforelasticsearch.sql.expression.operator.arthmetic.ArithmeticFunction;
import com.amazon.opendistroforelasticsearch.sql.expression.operator.arthmetic.UnaryFunction;
import com.amazon.opendistroforelasticsearch.sql.expression.operator.arthmetic.MathematicalFunction;
import com.amazon.opendistroforelasticsearch.sql.expression.operator.predicate.BinaryPredicateOperator;
import com.amazon.opendistroforelasticsearch.sql.expression.operator.predicate.UnaryPredicateOperator;
import java.util.HashMap;
Expand All @@ -40,7 +40,7 @@ public BuiltinFunctionRepository functionRepository() {
new BuiltinFunctionRepository(new HashMap<>());
ArithmeticFunction.register(builtinFunctionRepository);
BinaryPredicateOperator.register(builtinFunctionRepository);
UnaryFunction.register(builtinFunctionRepository);
MathematicalFunction.register(builtinFunctionRepository);
UnaryPredicateOperator.register(builtinFunctionRepository);
AggregatorFunction.register(builtinFunctionRepository);
return builtinFunctionRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,22 @@
@Getter
@RequiredArgsConstructor
public enum BuiltinFunctionName {
/**
* Mathematical Functions.
*/
ABS(FunctionName.of("abs")),
CEIL(FunctionName.of("ceil")),
CEILING(FunctionName.of("ceiling")),
EXP(FunctionName.of("exp")),
FLOOR(FunctionName.of("floor")),
LN(FunctionName.of("ln")),
LOG(FunctionName.of("log")),
LOG10(FunctionName.of("log10")),
LOG2(FunctionName.of("log2")),

/**
* Text Functions.
*/
TOSTRING(FunctionName.of("tostring")),

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class FunctionName {
private final String functionName;

public static FunctionName of(String functionName) {
return new FunctionName(functionName);
return new FunctionName(functionName.toLowerCase());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,57 @@ public String toString() {
};
}

/**
* Construct {@link FunctionBuilder} which call function with arguments produced by observer1 and
* observer2 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 second 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 <R> the type of the result of the function
* @return {@link FunctionBuilder}
*/
public static <T, U, R> FunctionBuilder doubleArgFunc(
chloe-zh marked this conversation as resolved.
Show resolved Hide resolved
FunctionName functionName,
BiFunction<T, U, R> function,
Function<ExprValue, T> observer1,
Function<ExprValue, U> observer2,
ExprType returnType) {
return arguments ->
new FunctionExpression(functionName, arguments) {
@Override
public ExprValue valueOf(Environment<Expression, ExprValue> env) {
ExprValue arg1 = arguments.get(0).valueOf(env);
ExprValue arg2 = arguments.get(1).valueOf(env);
if (arg1.isMissing() || arg2.isMissing()) {
return ExprValueUtils.missingValue();
} else if (arg1.isNull() || arg2.isNull()) {
return ExprValueUtils.nullValue();
} else {
return ExprValueUtils.fromObjectValue(
function.apply(observer1.apply(arg1), observer2.apply(arg2)));
}
}

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

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

/**
* Construct {@link FunctionBuilder} which call function with arguments produced by observer In
* general, if any operand evaluates to a MISSING value, the enclosing operator will return
Expand Down
Loading