mihaibudiu commented on code in PR #3689:
URL: https://github.com/apache/calcite/pull/3689#discussion_r1494967077


##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -2788,6 +2788,18 @@ public static double log(BigDecimal d0, BigDecimal d1) {
     return Math.log(d0.doubleValue()) / Math.log(d1.doubleValue());
   }
 
+  /** SQL {@code LOG2(number)} function applied to double values. */
+  public static double log2(double d0) {
+    return (d0 == 0) ? Double.NaN : Math.log(d0) / Math.log(2);
+  }
+
+  /** SQL {@code LOG2(number)} function applied to
+   * BigDecimal and double values. */
+  public static double log2(BigDecimal d0) {
+    return (d0.doubleValue() == 0) ? Double.NaN : Math.log(d0.doubleValue()) / 
Math.log(2);

Review Comment:
   just call the other function.



##########
testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java:
##########
@@ -6222,6 +6222,41 @@ void checkRegexpExtract(SqlOperatorFixture f0, 
FunctionAlias functionAlias) {
     f.checkNull("log(10, cast(null as real))");
   }
 
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6224";>[CALCITE-6224]
+   * Add LOG2 function (enabled in MYSQL, Spark library)</a>. */
+  @Test void testLog2Func() {
+    final SqlOperatorFixture f0 = fixture();
+    f0.checkFails("^log2(4)^",
+        "No match found for function signature LOG2\\(<NUMERIC>\\)", false);
+    final Consumer<SqlOperatorFixture> consumer = f -> {
+      f.setFor(SqlLibraryOperators.LOG2);
+      f.checkScalarApprox("log2(2)", "DOUBLE NOT NULL",
+          isWithin(1.0, 0.000001));
+      f.checkScalarApprox("log2(4)", "DOUBLE NOT NULL",
+          isWithin(2.0, 0.000001));
+      f.checkScalarApprox("log2(65536)", "DOUBLE NOT NULL",
+          isWithin(16.0, 0.000001));
+      f.checkScalarApprox("log2(2.0/3)", "DOUBLE NOT NULL",
+          isWithin(-0.5849625007211561, 0.000001));
+      f.checkScalarApprox("log2(4.0/3)", "DOUBLE NOT NULL",
+          isWithin(0.4150374992788435, 0.000001));
+      f.checkScalarApprox("log2(0.5)", "DOUBLE NOT NULL",
+          isWithin(-1.0, 0.000001));
+      f.checkScalarApprox("log2(cast(10e8 as double))", "DOUBLE NOT NULL",
+          isWithin(29.897352853986263, 0.000001));
+      f.checkScalarApprox("log2(cast(10e8 as float))", "DOUBLE NOT NULL",
+          isWithin(29.897352853986263, 0.000001));
+      f.checkScalarApprox("log2(-2)", "DOUBLE NOT NULL",
+          "NaN");
+      f.checkScalarApprox("log2(0)", "DOUBLE NOT NULL",
+          "NaN");
+      f.checkNull("log2(cast(null as real))");

Review Comment:
   how about a test with just NULL, without the cast? that should work.



##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -2788,6 +2788,18 @@ public static double log(BigDecimal d0, BigDecimal d1) {
     return Math.log(d0.doubleValue()) / Math.log(d1.doubleValue());
   }
 
+  /** SQL {@code LOG2(number)} function applied to double values. */
+  public static double log2(double d0) {
+    return (d0 == 0) ? Double.NaN : Math.log(d0) / Math.log(2);

Review Comment:
   In general testing for equality FP values does not work.
   There are also two kinds of zeros in FP, +0 and -0.
   If the result from Math.log(0) is -Infinity, the more robust way to do this 
is to actually compute the log and check when the result is the negative 
infinity.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to