github-actions[bot] commented on code in PR #64622:
URL: https://github.com/apache/doris/pull/64622#discussion_r3432348429
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/SearchSignatureForRound.java:
##########
@@ -18,26 +18,86 @@
package org.apache.doris.nereids.trees.expressions.functions;
import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.CascadesContext;
+import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
+import org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnFE;
+import org.apache.doris.nereids.trees.expressions.Cast;
import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.literal.IntegerLikeLiteral;
import org.apache.doris.nereids.types.DoubleType;
import org.apache.doris.nereids.types.IntegerType;
+import org.apache.doris.nereids.types.coercion.Int32OrLessType;
+import org.apache.doris.qe.ConnectContext;
+import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.List;
/**
- * if argument 0 is float or double, we should return double signature for
round like function.
+ * Signature search for round-like functions (round, round_bankers, ceil,
floor, truncate).
*/
public interface SearchSignatureForRound extends ExplicitlyCastableSignature {
+
+ int DOUBLE_DECIMAL_RESULT_MAX_SCALE = 15;
+
@Override
default FunctionSignature searchSignature(List<FunctionSignature>
signatures) {
List<Expression> arguments = getArguments();
if (arguments.get(0).getDataType().isFloatLikeType()) {
if (arguments.size() == 1) {
return
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE);
} else if (arguments.size() == 2) {
+ if (arguments.get(0).getDataType().isDoubleType()
+ && isOptedIntoDecimalReroute()
+ && isNonNegativeIntegerLiteralAtMost(arguments.get(1),
+ DOUBLE_DECIMAL_RESULT_MAX_SCALE)) {
+ return ExplicitlyCastableSignature.super.searchSignature(
+ withoutFloatLikeReturnTypes(signatures));
+ }
return
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE,
IntegerType.INSTANCE);
}
}
return ExplicitlyCastableSignature.super.searchSignature(signatures);
}
+
+ static boolean isOptedIntoDecimalReroute() {
+ ConnectContext ctx = ConnectContext.get();
+ return ctx != null &&
ctx.getSessionVariable().roundDoubleReturnsDecimalForConstScale;
+ }
+
+ /**
+ * True iff scale folds to an integer literal whose value lies in the
closed range
+ * [0, maxValue].
+ */
+ static boolean isNonNegativeIntegerLiteralAtMost(Expression scale, int
maxValue) {
+ Expression folded = scale;
+ if (!folded.isLiteral() && !folded.isSlot()) {
+ ExpressionRewriteContext ctx = new
ExpressionRewriteContext(CascadesContext.initTempContext());
+ folded = FoldConstantRuleOnFE.evaluate(folded, ctx);
+ }
+ Expression unwrapped = folded;
+ if (unwrapped instanceof Cast && unwrapped.child(0).isLiteral()
+ && unwrapped.child(0).getDataType() instanceof
Int32OrLessType) {
+ unwrapped = unwrapped.child(0);
+ }
+ if (!(unwrapped instanceof IntegerLikeLiteral)) {
+ return false;
+ }
+ Number number = ((IntegerLikeLiteral) unwrapped).getNumber();
+ BigInteger value = (number instanceof BigInteger)
+ ? (BigInteger) number
+ : BigInteger.valueOf(number.longValue());
+ return value.signum() >= 0 &&
value.compareTo(BigInteger.valueOf(maxValue)) <= 0;
+ }
Review Comment:
This now accepts in-range widened integer literals, but
`ComputePrecisionForRound` still only derives the result scale from
`Int32OrLessType` literals/casts. A reduced plan is:
```text
Project(round(d, CAST(2 AS BIGINT)))
Scan(d: DOUBLE)
```
`isNonNegativeIntegerLiteralAtMost` folds the scale to `BigIntLiteral(2)`
and selects the decimal overload. Later
`ComputePrecisionForRound.computePrecision` folds the same scale, sees
`BigIntType` rather than `Int32OrLessType`, and falls through to `scale =
decimalV3Type.getScale()` (15). The expression is therefore typed as
`DECIMALV3(30,15)` instead of scale 2, so rendering/metadata can become
`81.570000000000000` rather than `81.57`. This is distinct from the existing
overflow thread because the scale is inside `[0, 15]`. Please either keep this
predicate aligned with `ComputePrecisionForRound` (only accept int32-or-less
after folding/unwrapping) or teach `ComputePrecisionForRound` to use exact
widened integer values in range, and add a BIGINT/LARGEINT scale <= 15 test.
--
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]