You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by GitBox <gi...@apache.org> on 2020/09/24 23:28:03 UTC

[GitHub] [druid] jihoonson commented on a change in pull request #10429: vectorize remaining math expressions

jihoonson commented on a change in pull request #10429:
URL: https://github.com/apache/druid/pull/10429#discussion_r494620087



##########
File path: core/src/main/java/org/apache/druid/math/expr/ExprType.java
##########
@@ -216,11 +226,44 @@ public static ExprType functionAutoTypeConversion(@Nullable ExprType type, @Null
       return STRING;
     }
 
-    return numericAutoTypeConversion(type, other);
+    return doubleNumericAutoTypeConversion(type, other);
   }
 
+  /**
+   * Given 2 'input' types, choose the most appropriate combined type, if possible
+   *
+   * arrays must be the same type
+   * if either type is {@link #STRING}, the output type will be preserved as string
+   * any number will be coerced to {@link #LONG}
+   */
+  @Nullable
+  public static ExprType integerMathFunctionAutoTypeConversion(@Nullable ExprType type, @Nullable ExprType other)
+  {
+    if (type == null || other == null) {
+      // cannot auto conversion unknown types
+      return null;
+    }
+    // arrays cannot be auto converted
+    if (isArray(type) || isArray(other)) {
+      if (!type.equals(other)) {
+        throw new IAE("Cannot implicitly cast %s to %s", type, other);
+      }
+      return type;
+    }
+    // if either argument is a string, type becomes a string
+    if (STRING.equals(type) || STRING.equals(other)) {
+      return STRING;
+    }
+
+    // any number is long
+    return LONG;
+  }
+
+  /**
+   * If both types are {@link #LONG}, returns {@link #LONG}, else {@link #DOUBLE}
+   */
   @Nullable

Review comment:
       The return value is not nullable.

##########
File path: core/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java
##########
@@ -632,170 +793,812 @@ public double apply(double left, double right)
     );
   }
 
-  public static <T> ExprVectorProcessor<T> atan(Expr.VectorInputBindingTypes inputTypes, Expr arg)
+  public static <T> ExprVectorProcessor<T> atan2(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
   {
     return makeDoubleMathProcessor(
         inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(long left, long right)
           {
-            return Math.atan(input);
+            return Math.atan2(left, right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(long left, double right)
           {
-            return Math.atan(input);
+            return Math.atan2(left, right);
           }
-        }
-    );
-  }
-
-  public static <T> ExprVectorProcessor<T> cos(Expr.VectorInputBindingTypes inputTypes, Expr arg)
-  {
-    return makeDoubleMathProcessor(
-        inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(double left, long right)
           {
-            return Math.cos(input);
+            return Math.atan2(left, right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(double left, double right)
           {
-            return Math.cos(input);
+            return Math.atan2(left, right);
           }
         }
     );
   }
 
-  public static <T> ExprVectorProcessor<T> cosh(Expr.VectorInputBindingTypes inputTypes, Expr arg)
+  public static <T> ExprVectorProcessor<T> copySign(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
   {
     return makeDoubleMathProcessor(
         inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(long left, long right)
           {
-            return Math.cosh(input);
+            return Math.copySign((double) left, (double) right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(long left, double right)
           {
-            return Math.cosh(input);
+            return Math.copySign((double) left, right);
           }
-        }
-    );
-  }
-
-  public static <T> ExprVectorProcessor<T> cot(Expr.VectorInputBindingTypes inputTypes, Expr arg)
-  {
-    return makeDoubleMathProcessor(
-        inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(double left, long right)
           {
-            return Math.cos(input) / Math.sin(input);
+            return Math.copySign(left, (double) right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(double left, double right)
           {
-            return Math.cos(input) / Math.sin(input);
+            return Math.copySign(left, right);
           }
         }
     );
   }
 
-  public static <T> ExprVectorProcessor<T> sin(Expr.VectorInputBindingTypes inputTypes, Expr arg)
+  public static <T> ExprVectorProcessor<T> hypot(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
   {
     return makeDoubleMathProcessor(
         inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(long left, long right)
           {
-            return Math.sin(input);
+            return Math.hypot(left, right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(long left, double right)
           {
-            return Math.sin(input);
+            return Math.hypot(left, right);
           }
-        }
-    );
-  }
-
-  public static <T> ExprVectorProcessor<T> sinh(Expr.VectorInputBindingTypes inputTypes, Expr arg)
-  {
-    return makeDoubleMathProcessor(
-        inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
-            inputTypes.getMaxVectorSize()
-        )
-        {
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, long right)
+          {
+            return Math.hypot(left, right);
+          }
+        },
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, double right)
+          {
+            return Math.hypot(left, right);
+          }
+        }
+    );
+  }
+
+  public static <T> ExprVectorProcessor<T> remainder(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
+  {
+    return makeDoubleMathProcessor(
+        inputTypes,
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, long right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        },
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, double right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, long right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        },
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, double right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        }
+    );
+  }
+
+  public static <T> ExprVectorProcessor<T> nextAfter(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
+  {
+    return makeDoubleMathProcessor(
+        inputTypes,
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, long right)
+          {
+            return Math.nextAfter((double) left, (double) right);
+          }
+        },
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, double right)
+          {
+            return Math.nextAfter((double) left, right);
+          }
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, long right)
+          {
+            return Math.nextAfter(left, (double) right);
+          }
+        },
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, double right)
+          {
+            return Math.nextAfter(left, right);
+          }
+        }
+    );
+  }
+
+  public static <T> ExprVectorProcessor<T> scalb(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
+  {
+    return makeDoubleMathProcessor(
+        inputTypes,
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, long right)
+          {
+            return Math.scalb((double) left, (int) right);

Review comment:
       Same comment for other places where it does narrowing casting.

##########
File path: core/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java
##########
@@ -632,170 +793,812 @@ public double apply(double left, double right)
     );
   }
 
-  public static <T> ExprVectorProcessor<T> atan(Expr.VectorInputBindingTypes inputTypes, Expr arg)
+  public static <T> ExprVectorProcessor<T> atan2(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
   {
     return makeDoubleMathProcessor(
         inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(long left, long right)
           {
-            return Math.atan(input);
+            return Math.atan2(left, right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(long left, double right)
           {
-            return Math.atan(input);
+            return Math.atan2(left, right);
           }
-        }
-    );
-  }
-
-  public static <T> ExprVectorProcessor<T> cos(Expr.VectorInputBindingTypes inputTypes, Expr arg)
-  {
-    return makeDoubleMathProcessor(
-        inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(double left, long right)
           {
-            return Math.cos(input);
+            return Math.atan2(left, right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(double left, double right)
           {
-            return Math.cos(input);
+            return Math.atan2(left, right);
           }
         }
     );
   }
 
-  public static <T> ExprVectorProcessor<T> cosh(Expr.VectorInputBindingTypes inputTypes, Expr arg)
+  public static <T> ExprVectorProcessor<T> copySign(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
   {
     return makeDoubleMathProcessor(
         inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(long left, long right)
           {
-            return Math.cosh(input);
+            return Math.copySign((double) left, (double) right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(long left, double right)
           {
-            return Math.cosh(input);
+            return Math.copySign((double) left, right);
           }
-        }
-    );
-  }
-
-  public static <T> ExprVectorProcessor<T> cot(Expr.VectorInputBindingTypes inputTypes, Expr arg)
-  {
-    return makeDoubleMathProcessor(
-        inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(double left, long right)
           {
-            return Math.cos(input) / Math.sin(input);
+            return Math.copySign(left, (double) right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(double left, double right)
           {
-            return Math.cos(input) / Math.sin(input);
+            return Math.copySign(left, right);
           }
         }
     );
   }
 
-  public static <T> ExprVectorProcessor<T> sin(Expr.VectorInputBindingTypes inputTypes, Expr arg)
+  public static <T> ExprVectorProcessor<T> hypot(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
   {
     return makeDoubleMathProcessor(
         inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(long input)
+          public double apply(long left, long right)
           {
-            return Math.sin(input);
+            return Math.hypot(left, right);
           }
         },
-        () -> new DoubleOutDoubleInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
             inputTypes.getMaxVectorSize()
         )
         {
           @Override
-          public double apply(double input)
+          public double apply(long left, double right)
           {
-            return Math.sin(input);
+            return Math.hypot(left, right);
           }
-        }
-    );
-  }
-
-  public static <T> ExprVectorProcessor<T> sinh(Expr.VectorInputBindingTypes inputTypes, Expr arg)
-  {
-    return makeDoubleMathProcessor(
-        inputTypes,
-        arg,
-        () -> new DoubleOutLongInFunctionVectorProcessor(
-            arg.buildVectorized(inputTypes),
-            inputTypes.getMaxVectorSize()
-        )
-        {
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, long right)
+          {
+            return Math.hypot(left, right);
+          }
+        },
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, double right)
+          {
+            return Math.hypot(left, right);
+          }
+        }
+    );
+  }
+
+  public static <T> ExprVectorProcessor<T> remainder(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
+  {
+    return makeDoubleMathProcessor(
+        inputTypes,
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, long right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        },
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, double right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, long right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        },
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, double right)
+          {
+            return Math.IEEEremainder(left, right);
+          }
+        }
+    );
+  }
+
+  public static <T> ExprVectorProcessor<T> nextAfter(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
+  {
+    return makeDoubleMathProcessor(
+        inputTypes,
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, long right)
+          {
+            return Math.nextAfter((double) left, (double) right);
+          }
+        },
+        () -> new DoubleOutLongDoubleInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, double right)
+          {
+            return Math.nextAfter((double) left, right);
+          }
+        },
+        () -> new DoubleOutDoubleLongInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, long right)
+          {
+            return Math.nextAfter(left, (double) right);
+          }
+        },
+        () -> new DoubleOutDoublesInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(double left, double right)
+          {
+            return Math.nextAfter(left, right);
+          }
+        }
+    );
+  }
+
+  public static <T> ExprVectorProcessor<T> scalb(Expr.VectorInputBindingTypes inputTypes, Expr left, Expr right)
+  {
+    return makeDoubleMathProcessor(
+        inputTypes,
+        left,
+        right,
+        () -> new DoubleOutLongsInFunctionVectorProcessor(
+            left.buildVectorized(inputTypes),
+            right.buildVectorized(inputTypes),
+            inputTypes.getMaxVectorSize()
+        )
+        {
+          @Override
+          public double apply(long left, long right)
+          {
+            return Math.scalb((double) left, (int) right);

Review comment:
       Hmm, do we need a sanity check after a casting if the `right` value is still valid?




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org