This is an automated email from the ASF dual-hosted git repository. huajianlan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new ae87415174 [Feature](Nereids) add simplify arithmetic rule (#15242) ae87415174 is described below commit ae874151746157528386674571abf264fbfce8d4 Author: shee <13843187+qz...@users.noreply.github.com> AuthorDate: Mon Dec 26 16:57:59 2022 +0800 [Feature](Nereids) add simplify arithmetic rule (#15242) support simplify arithmetic rule for example : a + 1 > 1 => a > 0 --- .../rewrite/ExpressionNormalization.java | 6 +- .../rules/SimplifyArithmeticComparisonRule.java | 103 +++++++++++ .../rewrite/rules/SimplifyArithmeticRule.java | 194 +++++++++++++++++++++ .../org/apache/doris/nereids/util/TypeUtils.java | 55 ++++++ .../rewrite/ExpressionRewriteTestHelper.java | 2 +- .../rewrite/SimplifyArithmeticRuleTest.java | 93 ++++++++++ 6 files changed, 451 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java index d79a9bb62e..484eac94bf 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionNormalization.java @@ -23,6 +23,8 @@ import org.apache.doris.nereids.rules.expression.rewrite.rules.DigitalMaskingCon import org.apache.doris.nereids.rules.expression.rewrite.rules.FoldConstantRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.InPredicateToEqualToRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.NormalizeBinaryPredicatesRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyArithmeticComparisonRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyArithmeticRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyCastRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyNotExprRule; import org.apache.doris.nereids.rules.expression.rewrite.rules.TypeCoercion; @@ -43,10 +45,12 @@ public class ExpressionNormalization extends ExpressionRewrite { InPredicateToEqualToRule.INSTANCE, SimplifyNotExprRule.INSTANCE, CharacterLiteralTypeCoercion.INSTANCE, + SimplifyArithmeticRule.INSTANCE, TypeCoercion.INSTANCE, FoldConstantRule.INSTANCE, SimplifyCastRule.INSTANCE, - DigitalMaskingConvert.INSTANCE + DigitalMaskingConvert.INSTANCE, + SimplifyArithmeticComparisonRule.INSTANCE ); public ExpressionNormalization(ConnectContext context) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyArithmeticComparisonRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyArithmeticComparisonRule.java new file mode 100644 index 0000000000..16aee8d2ad --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyArithmeticComparisonRule.java @@ -0,0 +1,103 @@ +// 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.doris.nereids.rules.expression.rewrite.rules; + +import org.apache.doris.nereids.rules.expression.rewrite.AbstractExpressionRewriteRule; +import org.apache.doris.nereids.rules.expression.rewrite.ExpressionRewriteContext; +import org.apache.doris.nereids.trees.expressions.Add; +import org.apache.doris.nereids.trees.expressions.ComparisonPredicate; +import org.apache.doris.nereids.trees.expressions.EqualTo; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.GreaterThan; +import org.apache.doris.nereids.trees.expressions.GreaterThanEqual; +import org.apache.doris.nereids.trees.expressions.LessThan; +import org.apache.doris.nereids.trees.expressions.LessThanEqual; +import org.apache.doris.nereids.trees.expressions.Multiply; +import org.apache.doris.nereids.trees.expressions.Subtract; +import org.apache.doris.nereids.util.TypeUtils; + +import com.google.common.collect.ImmutableList; + +/** + * Simplify arithmetic comparison rule. + * a + 1 > 1 => a > 0 + * a / -2 > 1 => a < -2 + */ +public class SimplifyArithmeticComparisonRule extends AbstractExpressionRewriteRule { + public static final SimplifyArithmeticComparisonRule INSTANCE = new SimplifyArithmeticComparisonRule(); + + @Override + public Expression visit(Expression expr, ExpressionRewriteContext context) { + return expr; + } + + private Expression process(ComparisonPredicate predicate) { + Expression left = predicate.left(); + Expression right = predicate.right(); + if (TypeUtils.isAddOrSubtract(left)) { + Expression p = left.child(1); + if (p.isConstant()) { + if (TypeUtils.isAdd(left)) { + right = new Subtract(right, p); + } + if (TypeUtils.isSubtract(left)) { + right = new Add(right, p); + } + left = left.child(0); + } + } + if (TypeUtils.isDivide(left)) { + Expression p = left.child(1); + if (p.isLiteral()) { + right = new Multiply(right, p); + left = left.child(0); + if (p.toString().startsWith("-")) { + Expression tmp = right; + right = left; + left = tmp; + } + } + } + return predicate.withChildren(ImmutableList.of(left, right)); + } + + @Override + public Expression visitGreaterThan(GreaterThan greaterThan, ExpressionRewriteContext context) { + return process(greaterThan); + } + + @Override + public Expression visitGreaterThanEqual(GreaterThanEqual greaterThanEqual, ExpressionRewriteContext context) { + return process(greaterThanEqual); + } + + @Override + public Expression visitEqualTo(EqualTo equalTo, ExpressionRewriteContext context) { + return process(equalTo); + } + + @Override + public Expression visitLessThan(LessThan lessThan, ExpressionRewriteContext context) { + return process(lessThan); + } + + @Override + public Expression visitLessThanEqual(LessThanEqual lessThanEqual, ExpressionRewriteContext context) { + return process(lessThanEqual); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyArithmeticRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyArithmeticRule.java new file mode 100644 index 0000000000..00c9189117 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/SimplifyArithmeticRule.java @@ -0,0 +1,194 @@ +// 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.doris.nereids.rules.expression.rewrite.rules; + +import org.apache.doris.nereids.rules.expression.rewrite.AbstractExpressionRewriteRule; +import org.apache.doris.nereids.rules.expression.rewrite.ExpressionRewriteContext; +import org.apache.doris.nereids.trees.expressions.Add; +import org.apache.doris.nereids.trees.expressions.BinaryArithmetic; +import org.apache.doris.nereids.trees.expressions.Divide; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.Multiply; +import org.apache.doris.nereids.trees.expressions.Subtract; +import org.apache.doris.nereids.util.TypeUtils; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Optional; + +/** + * Simplify arithmetic rule. + * This rule run before `FoldConstantRule`. + * For example: + * a + 1 + b - 2 - ((c - d) + 1) => a + b - c + d + (1 - 2 - 1) + * After `FoldConstantRule`: + * a + b - c + d + (1 - 2 - 1) => a + b - c + d - 2 + */ +public class SimplifyArithmeticRule extends AbstractExpressionRewriteRule { + public static final SimplifyArithmeticRule INSTANCE = new SimplifyArithmeticRule(); + + @Override + public Expression visitAdd(Add add, ExpressionRewriteContext context) { + return process(add, true); + } + + @Override + public Expression visitSubtract(Subtract subtract, ExpressionRewriteContext context) { + return process(subtract, true); + } + + @Override + public Expression visitDivide(Divide divide, ExpressionRewriteContext context) { + return process(divide, false); + } + + @Override + public Expression visitMultiply(Multiply multiply, ExpressionRewriteContext context) { + return process(multiply, false); + } + + /** + * The main logic is as follows: + * 1.flatten the arithmetic expression. + * a + 1 + b - 2 - ((c - d) + 1) => a + 1 + b -2 - c + d - 1 + * 2.move variables to left side and move constants to right sid. + * a + 1 + b -2 - c + d - 1 => a + b - c + d + 1 - 2 - 1 + * 3.build new arithmetic expression. + * (a + b - c + d) + (1 - 2 - 1) + */ + private Expression process(BinaryArithmetic arithmetic, boolean isAddOrSub) { + // 1. flatten the arithmetic expression. + List<Operand> flattedExpressions = flatten(arithmetic, isAddOrSub); + + List<Operand> variables = Lists.newArrayList(); + List<Operand> constants = Lists.newArrayList(); + + // 2. move variables to left side and move constants to right sid. + flattedExpressions.forEach(operand -> { + if (operand.expression.isConstant()) { + constants.add(operand); + } else { + variables.add(operand); + } + }); + + // 3. build new arithmetic expression. + if (!constants.isEmpty()) { + boolean isOpposite = !constants.get(0).flag; + Optional<Operand> c = constants.stream().reduce((x, y) -> { + Expression expr; + if (isOpposite && y.flag || !isOpposite && !y.flag) { + expr = getSubOrDivide(isAddOrSub, x, y); + } else { + expr = getAddOrMultiply(isAddOrSub, x, y); + } + return Operand.of(true, expr); + }); + variables.add(Operand.of(!isOpposite, c.get().expression)); + } + + Optional<Operand> result = variables.stream().reduce((x, y) -> !y.flag + ? Operand.of(true, getSubOrDivide(isAddOrSub, x, y)) + : Operand.of(true, getAddOrMultiply(isAddOrSub, x, y))); + + if (result.isPresent()) { + return result.get().expression; + } else { + return arithmetic; + } + } + + private List<Operand> flatten(Expression expr, boolean isAddOrSub) { + List<Operand> result = Lists.newArrayList(); + if (isAddOrSub) { + flattenAddSubtract(true, expr, result); + } else { + flattenMultiplyDivide(true, expr, result); + } + return result; + } + + private void flattenAddSubtract(boolean flag, Expression expr, List<Operand> result) { + if (TypeUtils.isAddOrSubtract(expr)) { + BinaryArithmetic arithmetic = (BinaryArithmetic) expr; + flattenAddSubtract(flag, arithmetic.left(), result); + if (TypeUtils.isSubtract(expr) && !flag) { + flattenAddSubtract(true, arithmetic.right(), result); + } else if (TypeUtils.isAdd(expr) && !flag) { + flattenAddSubtract(false, arithmetic.right(), result); + } else { + flattenAddSubtract(!TypeUtils.isSubtract(expr), arithmetic.right(), result); + } + } else { + result.add(Operand.of(flag, expr)); + } + } + + private void flattenMultiplyDivide(boolean flag, Expression expr, List<Operand> result) { + if (TypeUtils.isMultiplyOrDivide(expr)) { + BinaryArithmetic arithmetic = (BinaryArithmetic) expr; + flattenMultiplyDivide(flag, arithmetic.left(), result); + if (TypeUtils.isDivide(expr) && !flag) { + flattenMultiplyDivide(true, arithmetic.right(), result); + } else if (TypeUtils.isMultiply(expr) && !flag) { + flattenMultiplyDivide(false, arithmetic.right(), result); + } else { + flattenMultiplyDivide(!TypeUtils.isDivide(expr), arithmetic.right(), result); + } + } else { + result.add(Operand.of(flag, expr)); + } + } + + private Expression getSubOrDivide(boolean isAddOrSub, Operand x, Operand y) { + return isAddOrSub ? new Subtract(x.expression, y.expression) + : new Divide(x.expression, y.expression); + } + + private Expression getAddOrMultiply(boolean isAddOrSub, Operand x, Operand y) { + return isAddOrSub ? new Add(x.expression, y.expression) + : new Multiply(x.expression, y.expression); + } + + /** + * Operational operand. + * `flag` is true indicates that the operand's operator is `Add`, + * otherwise operand's operator is `Subtract in add-subtract. + * `flag` is true indicates that the operand's operator is `Multiply`, + * otherwise operand's operator is `Divide in multiply-divide. + */ + public static class Operand { + boolean flag; + Expression expression; + + public Operand(boolean flag, Expression expression) { + this.flag = flag; + this.expression = expression; + } + + public static Operand of(boolean flag, Expression expression) { + return new Operand(flag, expression); + } + + @Override + public String toString() { + return flag + " : " + expression; + } + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeUtils.java new file mode 100644 index 0000000000..318f1155bb --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeUtils.java @@ -0,0 +1,55 @@ +// 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.doris.nereids.util; + +import org.apache.doris.nereids.trees.expressions.Add; +import org.apache.doris.nereids.trees.expressions.Divide; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.Multiply; +import org.apache.doris.nereids.trees.expressions.Subtract; + +/** + * Judgment expression type. + */ +public class TypeUtils { + + public static boolean isAddOrSubtract(Expression expr) { + return isAdd(expr) || isSubtract(expr); + } + + public static boolean isAdd(Expression expr) { + return expr instanceof Add; + } + + public static boolean isSubtract(Expression expr) { + return expr instanceof Subtract; + } + + public static boolean isMultiplyOrDivide(Expression expr) { + return isMultiply(expr) || isDivide(expr); + } + + public static boolean isDivide(Expression expr) { + return expr instanceof Divide; + } + + public static boolean isMultiply(Expression expr) { + return expr instanceof Multiply; + } + +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTestHelper.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTestHelper.java index 98b97bee15..f4aabee6f4 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTestHelper.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/ExpressionRewriteTestHelper.java @@ -68,7 +68,7 @@ public abstract class ExpressionRewriteTestHelper { Expression expectedExpression = PARSER.parseExpression(expected); expectedExpression = typeCoercion(replaceUnboundSlot(expectedExpression, mem)); Expression rewrittenExpression = executor.rewrite(needRewriteExpression); - Assertions.assertEquals(expectedExpression, rewrittenExpression); + Assertions.assertEquals(expectedExpression.toSql(), rewrittenExpression.toSql()); } private Expression replaceUnboundSlot(Expression expression, Map<String, Slot> mem) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/SimplifyArithmeticRuleTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/SimplifyArithmeticRuleTest.java new file mode 100644 index 0000000000..68a8efbbe7 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rewrite/SimplifyArithmeticRuleTest.java @@ -0,0 +1,93 @@ +// 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.doris.nereids.rules.expression.rewrite; + +import org.apache.doris.nereids.rules.expression.rewrite.rules.FoldConstantRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyArithmeticComparisonRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.SimplifyArithmeticRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.TypeCoercion; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Test; + +public class SimplifyArithmeticRuleTest extends ExpressionRewriteTestHelper { + @Test + public void testSimplifyArithmetic() { + executor = new ExpressionRuleExecutor(ImmutableList.of( + SimplifyArithmeticRule.INSTANCE, + TypeCoercion.INSTANCE, + FoldConstantRule.INSTANCE + )); + assertRewriteAfterTypeCoercion("IA", "IA"); + assertRewriteAfterTypeCoercion("IA + 1", "IA + 1"); + assertRewriteAfterTypeCoercion("IA + IB", "IA + IB"); + assertRewriteAfterTypeCoercion("1 + 1", "2"); + assertRewriteAfterTypeCoercion("IA + 2 - 1", "cast(IA as bigint) + 1"); + assertRewriteAfterTypeCoercion("IA + 2 - (1 - 1)", "cast(IA as bigint) + 2"); + assertRewriteAfterTypeCoercion("IA + 2 - ((1 - IB) - (3 + IC))", "IA + IB + cast(IC as BIGINT) + 4"); + assertRewriteAfterTypeCoercion("IA * IB + 2 - IC * 2", "(IA * IB) - (IC * 2) + 2"); + assertRewriteAfterTypeCoercion("IA * IB", "IA * IB"); + assertRewriteAfterTypeCoercion("IA * IB / 2 * 2", "cast((IA * IB) as DOUBLE) / 1.0"); + assertRewriteAfterTypeCoercion("IA * IB / (2 * 2)", "cast((IA * IB) as DOUBLE) / 4.0"); + assertRewriteAfterTypeCoercion("IA * IB / (2 * 2)", "cast((IA * IB) as DOUBLE) / 4.0"); + assertRewriteAfterTypeCoercion("IA * (IB / 2) * 2)", "cast(IA as DOUBLE) * cast(IB as DOUBLE) / 1.0"); + assertRewriteAfterTypeCoercion("IA * (IB / 2) * (IC + 1))", "cast(IA as DOUBLE) * cast(IB as DOUBLE) * cast((IC + 1) as DOUBLE) / 2.0"); + assertRewriteAfterTypeCoercion("IA * IB / 2 / IC * 2 * ID / 4", "(((cast((IA * IB) as DOUBLE) / cast(IC as DOUBLE)) * cast(ID as DOUBLE)) / 4.0)"); + } + + @Test + public void testSimplifyArithmeticComparison() { + executor = new ExpressionRuleExecutor(ImmutableList.of( + SimplifyArithmeticRule.INSTANCE, + TypeCoercion.INSTANCE, + FoldConstantRule.INSTANCE, + SimplifyArithmeticComparisonRule.INSTANCE, + SimplifyArithmeticRule.INSTANCE, + TypeCoercion.INSTANCE, + FoldConstantRule.INSTANCE + )); + assertRewriteAfterTypeCoercion("IA", "IA"); + assertRewriteAfterTypeCoercion("IA > IB", "IA > IB"); + assertRewriteAfterTypeCoercion("IA - 1 > 1", "cast(IA as bigint) > 2"); + assertRewriteAfterTypeCoercion("IA + 1 - 1 >= 1", "cast(IA as bigint) >= 1"); + assertRewriteAfterTypeCoercion("IA - 1 - 1 < 1", "cast(IA as bigint) < 3"); + assertRewriteAfterTypeCoercion("IA - 1 - 1 = 1", "cast(IA as bigint) = 3"); + assertRewriteAfterTypeCoercion("IA + (1 - 1) >= 1", "cast(IA as bigint) >= 1"); + assertRewriteAfterTypeCoercion("IA - 1 * 1 = 1", "cast(IA as bigint) = 2"); + assertRewriteAfterTypeCoercion("IA + 1 + 1 > IB", "cast(IA as BIGINT) > cast(IB as BIGINT) - 2"); + assertRewriteAfterTypeCoercion("IA + 1 > IB", "cast(IA as BIGINT) > cast(IB as BIGINT) - 1)"); + assertRewriteAfterTypeCoercion("IA + 1 - (IB - 1) > 1", "IA - IB > -1"); + assertRewriteAfterTypeCoercion("IA + 1 - (IB * IC - 1) > 1", "cast(IA as bigint) - IB * IC > -1"); + assertRewriteAfterTypeCoercion("IA + 1 - (IB * IC - 1) > 1", "cast(IA as bigint) - IB * IC > -1"); + assertRewriteAfterTypeCoercion("IA + 1 - (IB * IC - 1) > 1", "cast(IA as bigint) - IB * IC > -1"); + assertRewriteAfterTypeCoercion("(IA - 1) + (IB + 1) - (IC - 1) > 1", "IA + IB - cast(IC as BIGINT) > 0"); + assertRewriteAfterTypeCoercion("(IA - 1) + (IB + 1) - ((IC - 1) - (ID + 1)) > 1", "IA + IB - cast(IC as BIGINT) + cast(ID as BIGINT) > -1"); + assertRewriteAfterTypeCoercion("(IA - 1) + (IB + 1) - ((IC - 1) - (ID * IE + 1)) > 1", "IA + IB - cast(IC as BIGINT) + ID * IE > -1"); + assertRewriteAfterTypeCoercion("IA + 1 - (IB - 1) > IC + 1 - 1 + ID", "IA - IB > cast(IC as bigint) + cast(ID as bigint) + -2"); + assertRewriteAfterTypeCoercion("IA + 1 - (IB - 1) > IC - 1", "IA - IB > cast(IC as bigint) - 3"); + assertRewriteAfterTypeCoercion("IA + 1 > IB - 1", "cast(IA as bigint) > cast(IB as bigint) - 2"); + assertRewriteAfterTypeCoercion("IA > IB - 1", "cast(IA as bigint) > IB - 1"); + assertRewriteAfterTypeCoercion("IA + 1 > IB", "cast(IA as BIGINT) > (cast(IB as BIGINT) - 1)"); + assertRewriteAfterTypeCoercion("IA + 1 > IB * IC", "cast(IA as BIGINT) > ((IB * IC) - 1)"); + assertRewriteAfterTypeCoercion("IA * ID > IB * IC", "IA * ID > IB * IC"); + assertRewriteAfterTypeCoercion("IA * ID / 2 > IB * IC", "cast((IA * ID) as DOUBLE) > cast((IB * IC) as DOUBLE) * 2.0"); + assertRewriteAfterTypeCoercion("IA * ID / -2 > IB * IC", "cast((IB * IC) as DOUBLE) * -2.0 > cast((IA * ID) as DOUBLE)"); + } + +} + --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org