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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]