[fix](Nereids) SimplifyArithmeticRule generate wrong expression after process (#15580)

in the case of 'a / b', if a is constant, after apple SimplifyArithmeticRule, expression will be convert to 'b * a' by mistake.
This commit is contained in:
morrySnow
2023-01-04 11:10:15 +08:00
committed by GitHub
parent f2f06c1acc
commit 7728794b4a
4 changed files with 16 additions and 2 deletions

View File

@ -39,6 +39,8 @@ import java.util.Optional;
* 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
*
* TODO: handle cases like: '1 - IA < 1' to 'IA > 0'
*/
public class SimplifyArithmeticRule extends AbstractExpressionRewriteRule {
public static final SimplifyArithmeticRule INSTANCE = new SimplifyArithmeticRule();
@ -100,7 +102,12 @@ public class SimplifyArithmeticRule extends AbstractExpressionRewriteRule {
}
return Operand.of(true, expr);
});
variables.add(Operand.of(!isOpposite, c.get().expression));
boolean firstVariableFlag = variables.isEmpty() || variables.get(0).flag;
if (isOpposite || firstVariableFlag) {
variables.add(Operand.of(!isOpposite, c.get().expression));
} else {
variables.add(0, Operand.of(!isOpposite, c.get().expression));
}
}
Optional<Operand> result = variables.stream().reduce((x, y) -> !y.flag

View File

@ -122,7 +122,7 @@ public abstract class Expression extends AbstractTreeNode<Expression> implements
/**
* Whether the expression is a constant.
*/
public final boolean isConstant() {
public boolean isConstant() {
if (this instanceof LeafExpression) {
return this instanceof Literal;
} else {

View File

@ -65,6 +65,11 @@ public class Count extends AggregateFunction implements AlwaysNotNullable, Custo
return FunctionSignature.of(BigIntType.INSTANCE, (List) getArgumentsTypes());
}
@Override
public boolean isConstant() {
return false;
}
@Override
protected List<DataType> intermediateTypes() {
return ImmutableList.of(BigIntType.INSTANCE);

View File

@ -36,6 +36,8 @@ public class SimplifyArithmeticRuleTest extends ExpressionRewriteTestHelper {
assertRewriteAfterTypeCoercion("IA", "IA");
assertRewriteAfterTypeCoercion("IA + 1", "IA + 1");
assertRewriteAfterTypeCoercion("IA + IB", "IA + IB");
assertRewriteAfterTypeCoercion("1 * 3 / IA", "(3.0 / cast(IA as DOUBLE))");
assertRewriteAfterTypeCoercion("1 - IA", "1 - IA");
assertRewriteAfterTypeCoercion("1 + 1", "2");
assertRewriteAfterTypeCoercion("IA + 2 - 1", "cast(IA as bigint) + 1");
assertRewriteAfterTypeCoercion("IA + 2 - (1 - 1)", "cast(IA as bigint) + 2");