Skip to content
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 @@ -225,6 +225,7 @@
import static org.apache.calcite.sql.fun.SqlLibraryOperators.FROM_HEX;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.GETBIT;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.HEX;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.HYPOT;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ILIKE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.IS_INF;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.IS_NAN;
Expand Down Expand Up @@ -880,6 +881,7 @@ void populate1() {
defineMethod(CSCH, BuiltInMethod.CSCH.method, NullPolicy.STRICT);
defineMethod(DEGREES, BuiltInMethod.DEGREES.method, NullPolicy.STRICT);
defineMethod(FACTORIAL, BuiltInMethod.FACTORIAL.method, NullPolicy.STRICT);
defineMethod(HYPOT, BuiltInMethod.HYPOT.method, NullPolicy.STRICT);
defineMethod(IS_INF, BuiltInMethod.IS_INF.method, NullPolicy.STRICT);
defineMethod(IS_NAN, BuiltInMethod.IS_NAN.method, NullPolicy.STRICT);
defineMethod(POW, BuiltInMethod.POWER.method, NullPolicy.STRICT);
Expand Down
12 changes: 12 additions & 0 deletions core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -4319,6 +4319,18 @@ public static double degrees(double b0) {
return CombinatoricsUtils.factorial(b0);
}

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

/** SQL <code>HYPOT</code> operator applied to general numeric values. */
public static double hypot(Object a, Object b) {
final Number left = (Number) a;
final Number right = (Number) b;
return hypot(left.doubleValue(), right.doubleValue());
}

/** SQL <code>IS_INF</code> operator applied to BigDecimal values. */
public static boolean isInf(BigDecimal b0) {
return Double.isInfinite(b0.doubleValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import static org.apache.calcite.sql.fun.SqlLibrary.ALL;
import static org.apache.calcite.sql.fun.SqlLibrary.BIG_QUERY;
import static org.apache.calcite.sql.fun.SqlLibrary.CALCITE;
import static org.apache.calcite.sql.fun.SqlLibrary.CLICKHOUSE;
import static org.apache.calcite.sql.fun.SqlLibrary.HIVE;
import static org.apache.calcite.sql.fun.SqlLibrary.MSSQL;
import static org.apache.calcite.sql.fun.SqlLibrary.MYSQL;
Expand Down Expand Up @@ -2561,6 +2562,15 @@ private static RelDataType deriveTypeMapFromEntries(SqlOperatorBinding opBinding
OperandTypes.NUMERIC,
SqlFunctionCategory.STRING);

/** The {@code HYPOT(numeric1, numeric2)} function; returns
* sqrt(numeric1^2 + numeric2^2) without intermediate overflow or underflow. */
@LibraryOperator(libraries = {SPARK, CLICKHOUSE})
public static final SqlFunction HYPOT =
SqlBasicFunction.create("HYPOT",
ReturnTypes.DOUBLE_NULLABLE,
OperandTypes.NUMERIC_NUMERIC,
SqlFunctionCategory.NUMERIC);

@LibraryOperator(libraries = {BIG_QUERY, MYSQL, POSTGRESQL, SPARK, HIVE})
public static final SqlFunction MD5 =
SqlBasicFunction.create("MD5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ public enum BuiltInMethod {
TAND(SqlFunctions.class, "tand", double.class),
TANH(SqlFunctions.class, "tanh", long.class),
SINH(SqlFunctions.class, "sinh", long.class),
HYPOT(SqlFunctions.class, "hypot", double.class, double.class),
TRUNCATE(SqlFunctions.class, "truncate", String.class, int.class),
TRUNCATE_OR_PAD(SqlFunctions.class, "truncateOrPad", String.class, int.class),
TRIM(SqlFunctions.class, "trim", boolean.class, boolean.class, String.class,
Expand Down
1 change: 1 addition & 0 deletions site/_docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2936,6 +2936,7 @@ In the following:
| b | FORMAT_TIME(string, time) | Formats *time* according to the specified format *string*
| b | FORMAT_TIMESTAMP(string timestamp) | Formats *timestamp* according to the specified format *string*
| s | GETBIT(value, position) | Equivalent to `BIT_GET(value, position)`
| s i | HYPOT(numeric1, numeric2) | Returns sqrt(*numeric1*^2 + *numeric2*^2) without intermediate overflow or underflow
| b o p r s h | GREATEST(expr [, expr ]*) | Returns the greatest of the expressions
| b h s | IF(condition, value1, value2) | Returns *value1* if *condition* is TRUE, *value2* otherwise
| b s | IFNULL(value1, value2) | Equivalent to `NVL(value1, value2)`
Expand Down
54 changes: 54 additions & 0 deletions testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10018,6 +10018,60 @@ void checkArrayReverseFunc(SqlOperatorFixture f0, SqlFunction function,
f0.forEachLibrary(list(SqlLibrary.BIG_QUERY, SqlLibrary.SPARK), consumer);
}

/** Test case for <a href="https://issues.apache.org/jira/browse/CALCITE-6066">
* [CALCITE-6066] Add HYPOT function (enabled in Spark library)</a>. */
@Test void testHypotFunc() {
final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.HYPOT);
f0.checkFails("^hypot(3, 4)^",
"No match found for function signature HYPOT\\(<NUMERIC>, <NUMERIC>\\)",
false);
final Consumer<SqlOperatorFixture> consumer = f -> {
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.checkScalarApprox("hypot(cast(3 as float), cast(4 as real))", "DOUBLE NOT NULL",
isWithin(5.0000d, 0.0001d));
f.checkType("hypot(cast(null as bigint), 1)", "DOUBLE");
f.checkNull("hypot(cast(null as bigint), 1)");
f.checkNull("hypot(1, cast(null as bigint))");
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))");

// unsigned type
f.checkScalarApprox("hypot(cast(3 as integer unsigned), cast(4 as integer unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(cast(3 as bigint unsigned), cast(4 as integer unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(cast(3 as bigint unsigned), cast(4 as bigint unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(cast(3 as smallint unsigned), cast(4 as smallint unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(cast(3 as tinyint unsigned), cast(4 as tinyint unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));

// mixed type
f.checkScalarApprox("hypot(cast(3 as tinyint), cast(4 as tinyint unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(cast(3 as bigint), cast(4 as tinyint unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));
f.checkScalarApprox("hypot(cast(3 as double), cast(4 as tinyint unsigned))",
"DOUBLE NOT NULL", isWithin(5.0000d, 0.0001d));
};
f0.forEachLibrary(list(SqlLibrary.SPARK, SqlLibrary.CLICKHOUSE), consumer);
}

@Test void testInfinity() {
final SqlOperatorFixture f = fixture();
f.checkScalar("cast('Infinity' as double)", "Infinity",
Expand Down
Loading