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

Support trigonometric functions acos, asin, atan, atan2, cos, cot, degrees, radians, sin, tan #599

Merged
merged 7 commits into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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 @@ -21,7 +21,6 @@
import com.amazon.opendistroforelasticsearch.sql.expression.aggregation.Aggregator;
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 @@ -57,6 +56,21 @@ public static LiteralExpression literal(ExprValue value) {
return new LiteralExpression(value);
}

/**
* Wrap a number to {@link LiteralExpression}.
*/
public static LiteralExpression literal(Number value) {
if (value instanceof Integer) {
return new LiteralExpression(ExprValueUtils.integerValue(value.intValue()));
} else if (value instanceof Long) {
return new LiteralExpression(ExprValueUtils.longValue(value.longValue()));
} else if (value instanceof Float) {
return new LiteralExpression(ExprValueUtils.floatValue(value.floatValue()));
} else {
return new LiteralExpression(ExprValueUtils.doubleValue(value.doubleValue()));
}
}

public static ReferenceExpression ref(String ref, ExprType type) {
return new ReferenceExpression(ref, type);
}
Expand Down Expand Up @@ -133,6 +147,46 @@ public FunctionExpression truncate(Expression... expressions) {
return function(BuiltinFunctionName.TRUNCATE, expressions);
}

public FunctionExpression acos(Expression... expressions) {
return function(BuiltinFunctionName.ACOS, expressions);
}

public FunctionExpression asin(Expression... expressions) {
return function(BuiltinFunctionName.ASIN, expressions);
}

public FunctionExpression atan(Expression... expressions) {
return function(BuiltinFunctionName.ATAN, expressions);
}

public FunctionExpression atan2(Expression... expressions) {
return function(BuiltinFunctionName.ATAN2, expressions);
}

public FunctionExpression cos(Expression... expressions) {
return function(BuiltinFunctionName.COS, expressions);
}

public FunctionExpression cot(Expression... expressions) {
return function(BuiltinFunctionName.COT, expressions);
}

public FunctionExpression degrees(Expression... expressions) {
return function(BuiltinFunctionName.DEGREES, expressions);
}

public FunctionExpression radians(Expression... expressions) {
return function(BuiltinFunctionName.RADIANS, expressions);
}

public FunctionExpression sin(Expression... expressions) {
return function(BuiltinFunctionName.SIN, expressions);
}

public FunctionExpression tan(Expression... expressions) {
return function(BuiltinFunctionName.TAN, 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 @@ -34,6 +34,17 @@ public enum BuiltinFunctionName {
SQRT(FunctionName.of("sqrt")),
TRUNCATE(FunctionName.of("truncate")),

ACOS(FunctionName.of("acos")),
ASIN(FunctionName.of("asin")),
ATAN(FunctionName.of("atan")),
ATAN2(FunctionName.of("atan2")),
COS(FunctionName.of("cos")),
COT(FunctionName.of("cot")),
DEGREES(FunctionName.of("degrees")),
RADIANS(FunctionName.of("radians")),
SIN(FunctionName.of("sin")),
TAN(FunctionName.of("tan")),

/**
* Text Functions.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ public static void register(BuiltinFunctionRepository repository) {
repository.register(sign());
repository.register(sqrt());
repository.register(truncate());
repository.register(acos());
repository.register(asin());
repository.register(atan());
repository.register(atan2());
repository.register(cos());
repository.register(cot());
repository.register(degrees());
repository.register(radians());
repository.register(sin());
repository.register(tan());
}

/**
Expand Down Expand Up @@ -429,6 +439,154 @@ private static FunctionResolver truncate() {
.build());
}

/**
* Definition of acos(x) function.
* Calculates the arc cosine of x, that is, the value whose cosine is x.
* Returns NULL if x is not in the range -1 to 1.
* The supported signature of acos function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver acos() {
FunctionName functionName = BuiltinFunctionName.ACOS.getName();
return new FunctionResolver(
functionName,
singleArgumentFunction(functionName, v -> v < -1 || v > 1 ? null : Math.acos(v)));
}

/**
* Definition of asin(x) function.
* Calculates the arc sine of x, that is, the value whose sine is x.
* Returns NULL if x is not in the range -1 to 1.
* The supported signature of asin function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver asin() {
FunctionName functionName = BuiltinFunctionName.ASIN.getName();
return new FunctionResolver(
functionName,
singleArgumentFunction(functionName, v -> v < -1 || v > 1 ? null : Math.asin(v)));
}

/**
* Definition of atan(x) and atan(y, x) function.
* atan(x) calculates the arc tangent of x, that is, the value whose tangent is x.
* atan(y, x) calculates the arc tangent of y / x, except that the signs of both arguments
* are used to determine the quadrant of the result.
* The supported signature of atan function is
* (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> DOUBLE
*/
private static FunctionResolver atan() {
FunctionName functionName = BuiltinFunctionName.ATAN.getName();
return new FunctionResolver(functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(
new FunctionSignature(functionName, Arrays.asList(ExprCoreType.DOUBLE)),
unaryOperator(
functionName, Math::atan, ExprValueUtils::getDoubleValue, ExprCoreType.DOUBLE))
.put(
new FunctionSignature(
functionName, Arrays.asList(ExprCoreType.DOUBLE, ExprCoreType.DOUBLE)),
doubleArgFunc(functionName,
Math::atan2, ExprValueUtils::getDoubleValue, ExprValueUtils::getDoubleValue,
ExprCoreType.DOUBLE))
.build());
}

/**
* Definition of atan2(y, x) function.
* Calculates the arc tangent of y / x, except that the signs of both arguments
* are used to determine the quadrant of the result.
* The supported signature of atan2 function is
* (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> DOUBLE
*/
private static FunctionResolver atan2() {
FunctionName functionName = BuiltinFunctionName.ATAN2.getName();
return new FunctionResolver(functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(
new FunctionSignature(
functionName, Arrays.asList(ExprCoreType.DOUBLE, ExprCoreType.DOUBLE)),
doubleArgFunc(functionName,
Math::atan2, ExprValueUtils::getDoubleValue, ExprValueUtils::getDoubleValue,
ExprCoreType.DOUBLE))
.build());
}

/**
* Definition of cos(x) function.
* Calculates the cosine of X, where X is given in radians
* The supported signature of cos function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver cos() {
FunctionName functionName = BuiltinFunctionName.COS.getName();
return new FunctionResolver(functionName, singleArgumentFunction(functionName, Math::cos));
}

/**
* Definition of cot(x) function.
* Calculates the cotangent of x
* The supported signature of cot function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver cot() {
FunctionName functionName = BuiltinFunctionName.COT.getName();
return new FunctionResolver(
functionName,
singleArgumentFunction(functionName, v -> {
if (v == 0) {
throw new ArithmeticException(String.format("Out of range value for cot(%s)", v));
}
dai-chen marked this conversation as resolved.
Show resolved Hide resolved
return 1 / Math.tan(v);
}));
}

/**
* Definition of degrees(x) function.
* Converts x from radians to degrees
* The supported signature of degrees function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver degrees() {
FunctionName functionName = BuiltinFunctionName.DEGREES.getName();
return new FunctionResolver(
functionName, singleArgumentFunction(functionName, Math::toDegrees));
}

/**
* Definition of radians(x) function.
* Converts x from degrees to radians
* The supported signature of radians function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver radians() {
FunctionName functionName = BuiltinFunctionName.RADIANS.getName();
return new FunctionResolver(
functionName, singleArgumentFunction(functionName, Math::toRadians));
}

/**
* Definition of sin(x) function.
* Calculates the sine of x, where x is given in radians
* The supported signature of sin function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver sin() {
FunctionName functionName = BuiltinFunctionName.SIN.getName();
return new FunctionResolver(functionName, singleArgumentFunction(functionName, Math::sin));
}

/**
* Definition of tan(x) function.
* Calculates the tangent of x, where x is given in radians
* The supported signature of tan function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver tan() {
FunctionName functionName = BuiltinFunctionName.TAN.getName();
return new FunctionResolver(functionName, singleArgumentFunction(functionName, Math::tan));
}

/**
* Util method to generate single argument function bundles. Applicable for INTEGER -> INTEGER
* LONG -> LONG FLOAT -> FLOAT DOUBLE -> DOUBLE
Expand Down
Loading