clintropolis commented on a change in pull request #11904:
URL: https://github.com/apache/druid/pull/11904#discussion_r748659135
##########
File path: docs/misc/math-expr.md
##########
@@ -154,6 +154,7 @@ See javadoc of java.lang.Math for detailed explanation for
each function.
|remainder|remainder(x, y) returns the remainder operation on two arguments as
prescribed by the IEEE 754 standard|
|rint|rint(x) returns value that is closest in value to x and is equal to a
mathematical integer|
|round|round(x, y) returns the value of the x rounded to the y decimal places.
While x can be an integer or floating-point number, y must be an integer. The
type of the return value is specified by that of x. y defaults to 0 if omitted.
When y is negative, x is rounded on the left side of the y decimal points. If x
is `NaN`, x returns 0. If x is infinity, x will be converted to the nearest
finite double. |
+|safe_divide|safe_divide(x,y) returns the division of x by y if y is not equal
to 0. In case y is 0 it returns null or default values (if returning default
values are enabled). |
Review comment:
nit: to match other docs that describe difference between default and
sql compatible null handling mode
```suggestion
|safe_divide|safe_divide(x,y) returns the division of x by y if y is not
equal to 0. In case y is 0 it returns 0, or `null` if
`druid.generic.useDefaultValueForNull=false`. |
```
Also, since this file doesn't backtick the expression names, `safe_divide`
needs added to the spelling exceptions file
https://github.com/apache/druid/blob/master/website/.spelling#L1202
##########
File path: core/src/main/java/org/apache/druid/math/expr/Function.java
##########
@@ -1165,6 +1165,53 @@ protected ExprEval eval(double param)
}
}
+ class SafeDivide extends BivariateMathFunction
+ {
+ public static final String NAME = "safe_divide";
+
+ @Override
+ public String name()
+ {
+ return NAME ;
+ }
+
+ @Nullable
+ @Override
+ public ExpressionType getOutputType(Expr.InputBindingInspector inspector,
List<Expr> args)
+ {
+ ExpressionType type = ExpressionType.DOUBLE;
+ for (Expr arg : args) {
+ type = ExpressionTypeConversion.function(type,
arg.getOutputType(inspector));
+ }
+ return ExpressionType.asArrayType(type);
Review comment:
this shouldn't be array typed
```suggestion
return ExpressionTypeConversion.function(
args.get(0).getOutputType(inspector),
args.get(1).getOutputType(inspector)
);
```
Could you also add some tests with a mix of longs and doubles to
https://github.com/apache/druid/blob/master/core/src/test/java/org/apache/druid/math/expr/OutputTypeTest.java#L163?
##########
File path:
sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SafeDivideOperatorConversion.java
##########
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite.expression.builtin;
+
+import org.apache.calcite.sql.SqlFunction;
+import org.apache.calcite.sql.SqlFunctionCategory;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.type.OperandTypes;
+import org.apache.calcite.sql.type.ReturnTypes;
+import org.apache.druid.java.util.common.StringUtils;
+import org.apache.druid.math.expr.Function;
+import org.apache.druid.sql.calcite.expression.DirectOperatorConversion;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
+
+public class SafeDivideOperatorConversion extends DirectOperatorConversion
+{
+ private static final SqlFunction SQL_FUNCTION = OperatorConversions
+ .operatorBuilder(StringUtils.toUpperCase(Function.SafeDivide.NAME))
+ .operandTypeChecker(OperandTypes.ANY_NUMERIC)
+ .returnTypeInference(ReturnTypes.QUOTIENT_NULLABLE)
+ .functionCategory(SqlFunctionCategory.USER_DEFINED_FUNCTION)
Review comment:
nit: this could also probably be `SqlFunctionCategory.NUMERIC`, though
tbh i'm not sure if it matters that much?
##########
File path: docs/querying/sql.md
##########
@@ -414,9 +414,11 @@ to FLOAT. At runtime, Druid will widen 32-bit floats to
64-bit for most expressi
|`BITWISE_SHIFT_LEFT(expr1, expr2)`|Returns the result of `expr1 << expr2`.
Double values will be implicitly cast to longs, use
`BITWISE_CONVERT_DOUBLE_TO_LONG_BITS` to perform bitwise operations directly
with doubles|
|`BITWISE_SHIFT_RIGHT(expr1, expr2)`|Returns the result of `expr1 >> expr2`.
Double values will be implicitly cast to longs, use
`BITWISE_CONVERT_DOUBLE_TO_LONG_BITS` to perform bitwise operations directly
with doubles|
|`BITWISE_XOR(expr1, expr2)`|Returns the result of `expr1 ^ expr2`. Double
values will be implicitly cast to longs, use
`BITWISE_CONVERT_DOUBLE_TO_LONG_BITS` to perform bitwise operations directly
with doubles|
+|`DIV(x,y)`|Returns the result of integer division of x by y |
|`HUMAN_READABLE_BINARY_BYTE_FORMAT(value[, precision])`| Format a number in
human-readable [IEC](https://en.wikipedia.org/wiki/Binary_prefix) format. For
example, HUMAN_READABLE_BINARY_BYTE_FORMAT(1048576) returns `1.00 MiB`.
`precision` must be in the range of [0,3] (default: 2). |
|`HUMAN_READABLE_DECIMAL_BYTE_FORMAT(value[, precision])`| Format a number in
human-readable [SI](https://en.wikipedia.org/wiki/Binary_prefix) format.
HUMAN_READABLE_DECIMAL_BYTE_FORMAT(1048576) returns `1.04 MB`. `precision` must
be in the range of [0,3] (default: 2). `precision` must be in the range of
[0,3] (default: 2). |
|`HUMAN_READABLE_DECIMAL_FORMAT(value[, precision])`| Format a number in
human-readable SI format. For example, HUMAN_READABLE_DECIMAL_FORMAT(1048576)
returns `1.04 M`. `precision` must be in the range of [0,3] (default: 2). |
+|`SAFE_DIVIDE(x,y)`|Returns the division of x by y guarded on division by 0 |
Review comment:
```suggestion
|`SAFE_DIVIDE(x,y)`|Returns the division of x by y guarded on division by 0.
In case y is 0 it returns 0, or `null` if
`druid.generic.useDefaultValueForNull=false` |
```
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]