Skip to content

Commit

Permalink
[CALCITE-6066] Add HYPOT function (enabled in Spark library)
Browse files Browse the repository at this point in the history
  • Loading branch information
herunkang2018 committed Oct 28, 2023
1 parent 1e59338 commit 0d04207
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,4 @@ ExInst<RuntimeException> multipleCapturingGroupsForRegexpExtract(String value,

@BaseMessage("BIT_GET/GETBIT error: position {0,number} exceeds the bit upper limit {1,number}")
ExInst<CalciteException> illegalBitGetPositionExceedsLimit(int position, int size);

@BaseMessage("Argument to function ''{0}'' must be a positive number, but given value is ''{1}''")
ExInst<CalciteException> argumentMustBePositiveNumber(String a0, String a1);
}
17 changes: 4 additions & 13 deletions core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -3041,22 +3041,13 @@ public static double degrees(double b0) {
return Math.toDegrees(b0);
}

public static double hypot(long a, long b) {
return hypot(Double.valueOf(a), Double.valueOf(b));
}

public static double hypot(long a, double b) {
return hypot(Double.valueOf(a), b);
}

public static double hypot(double a, long b) {
return hypot(a, Double.valueOf(b));
/** SQL <code>HYPOT</code> operator applied to BigDecimal values. */
public static double hypot(BigDecimal a, BigDecimal b) {
return hypot(a.doubleValue(), b.doubleValue());
}

/** SQL <code>HYPOT</code> operator applied to double values. */
public static double hypot(double a, double b) {
if (a <= 0 || b <= 0) {
throw RESOURCE.argumentMustBePositiveNumber("HYPOT", String.valueOf(a < 0 ? a : b)).ex();
}
return Math.hypot(a, b);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1972,10 +1972,9 @@ private static RelDataType deriveTypeMapFromEntries(SqlOperatorBinding opBinding
OperandTypes.NUMERIC,
SqlFunctionCategory.NUMERIC);

/** The {@code HYPOT(numeric1, numeric2)} function; returns the hypotenuse
* of a right-angle triangle with two right-angle sides of {@code numeric1}
* and {@code numeric2}. */
@LibraryOperator(libraries = {SPARK, ORACLE})
/** The {@code HYPOT(numeric1, numeric2)} function; returns
* sqrt(numeric1^2+ numeric2^2) without intermediate overflow or underflow. */
@LibraryOperator(libraries = {SPARK})
public static final SqlFunction HYPOT =
SqlBasicFunction.create("HYPOT",
ReturnTypes.DOUBLE_NULLABLE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,5 +351,4 @@ MultipleRowSemanticsTables=A table function at most has one input table with row
NoOperator=No operator for ''{0}'' with kind: ''{1}'', syntax: ''{2}'' during JSON deserialization
IllegalNegativeBitGetPosition=BIT_GET/GETBIT error: negative position {0,number} not allowed
IllegalBitGetPositionExceedsLimit=BIT_GET/GETBIT error: position {0,number} exceeds the bit upper limit {1,number}
ArgumentMustBePositiveNumber=Argument to function ''{0}'' must be a positive number, but given value is ''{1}''
# End CalciteResource.properties
2 changes: 1 addition & 1 deletion site/_docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2739,7 +2739,7 @@ BigQuery's type system uses confusingly different names for types and functions:
| b | FORMAT_TIMESTAMP(string timestamp) | Formats *timestamp* according to the specified format *string*
| s | GETBIT(value, position) | Equivalent to `BIT_GET(value, position)`
| b o | GREATEST(expr [, expr ]*) | Returns the greatest of the expressions
| s o | HYPOT(numeric1, numeric2) | Returns the hypotenuse of a right-angle triangle with two right-angle sides of *numeric1* and *numeric2*
| s | HYPOT(numeric1, numeric2) | Returns sqrt(*numeric1*^2+ *numeric2*^2) without intermediate overflow or underflow
| b h s | IF(condition, value1, value2) | Returns *value1* if *condition* is TRUE, *value2* otherwise
| b | IFNULL(value1, value2) | Equivalent to `NVL(value1, value2)`
| p | string1 ILIKE string2 [ ESCAPE string3 ] | Whether *string1* matches pattern *string2*, ignoring case (similar to `LIKE`)
Expand Down
30 changes: 19 additions & 11 deletions testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7475,17 +7475,25 @@ private static void checkIf(SqlOperatorFixture f) {
f0.checkFails("^hypot(3, 4)^",
"No match found for function signature HYPOT\\(<NUMERIC>, <NUMERIC>\\)",
false);
final Consumer<SqlOperatorFixture> consumer = f -> {
f.checkType("hypot(3, 4)", "DOUBLE NOT NULL");
f.checkScalarApprox("hypot(3, 4)", "DOUBLE NOT NULL",
isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(2, 4)", "DOUBLE NOT NULL",
isWithin(4.4721d, 0.0001d));
f.checkNull("hypot(cast(null as bigint), 1)");
f.checkNull("hypot(cast(null as bigint), cast(null as bigint))");
f.checkNull("hypot(cast(null as double), cast(null as double))");
};
f0.forEachLibrary(list(SqlLibrary.SPARK, SqlLibrary.ORACLE), consumer);
final SqlOperatorFixture f = f0.withLibrary(SqlLibrary.SPARK);
f.checkScalarApprox("hypot(3, 4)", "DOUBLE NOT NULL",
isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(3.0, cast(4 as bigint))", "DOUBLE NOT NULL",
isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(cast(-2 as bigint), cast(-4 as bigint))",
"DOUBLE NOT NULL",
isWithin(4.4721d, 0.0001d));
f.checkScalarApprox("hypot(cast(3.0 as double), cast(4.0 as double))",
"DOUBLE NOT NULL",
isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(-2.5, cast(-4.5 as double))", "DOUBLE NOT NULL",
isWithin(5.1478d, 0.0001d));
f.checkScalarApprox("hypot(-2.5, -4.5)", "DOUBLE NOT NULL",
isWithin(5.1478d, 0.0001d));
f.checkNull("hypot(cast(null as bigint), 1)");
f.checkNull("hypot(cast(null as bigint), cast(null as bigint))");
f.checkNull("hypot(cast(null as double), cast(null as double))");
f.checkNull("hypot(cast(null as decimal), cast(null as decimal))");
}

@Test void testInfinity() {
Expand Down

0 comments on commit 0d04207

Please sign in to comment.