diff --git a/presto-docs/src/main/sphinx/functions/math.rst b/presto-docs/src/main/sphinx/functions/math.rst index 20b712d47fc3..00bcdbf5008c 100644 --- a/presto-docs/src/main/sphinx/functions/math.rst +++ b/presto-docs/src/main/sphinx/functions/math.rst @@ -89,6 +89,10 @@ Mathematical Functions Returns the natural logarithm of ``x``. +.. function:: log(b, x) -> double + + Returns the base ``b`` logarithm of ``x``. + .. function:: log2(x) -> double Returns the base 2 logarithm of ``x``. diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/MathFunctions.java b/presto-main/src/main/java/io/prestosql/operator/scalar/MathFunctions.java index 90f8545eda15..23f8f18efba4 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/MathFunctions.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/MathFunctions.java @@ -453,6 +453,14 @@ public static double ln(@SqlType(StandardTypes.DOUBLE) double num) return Math.log(num); } + @Description("logarithm to given base") + @ScalarFunction + @SqlType(StandardTypes.DOUBLE) + public static double log(@SqlType(StandardTypes.DOUBLE) double base, @SqlType(StandardTypes.DOUBLE) double number) + { + return Math.log(number) / Math.log(base); + } + @Description("logarithm to base 2") @ScalarFunction @SqlType(StandardTypes.DOUBLE) diff --git a/presto-main/src/test/java/io/prestosql/operator/scalar/TestMathFunctions.java b/presto-main/src/test/java/io/prestosql/operator/scalar/TestMathFunctions.java index e8f89d8867d9..92ac220c7590 100644 --- a/presto-main/src/test/java/io/prestosql/operator/scalar/TestMathFunctions.java +++ b/presto-main/src/test/java/io/prestosql/operator/scalar/TestMathFunctions.java @@ -473,6 +473,20 @@ public void testLog10() assertFunction("log10(NULL)", DOUBLE, null); } + @Test + public void testLog() + { + for (double doubleValue : DOUBLE_VALUES) { + for (double base : DOUBLE_VALUES) { + assertFunction("log(" + base + ", " + doubleValue + ")", DOUBLE, Math.log(doubleValue) / Math.log(base)); + assertFunction("log(REAL '" + (float) base + "', REAL'" + (float) doubleValue + "')", DOUBLE, Math.log((float) doubleValue) / Math.log((float) base)); + } + } + assertFunction("log(NULL, NULL)", DOUBLE, null); + assertFunction("log(5.0E0, NULL)", DOUBLE, null); + assertFunction("log(NULL, 5.0E0)", DOUBLE, null); + } + @Test public void testMod() {