This is an automated email from the ASF dual-hosted git repository. morrysnow 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 d53205076e [feature](Nereids) implicit cast StringLiteral to another side type of BinaryOperator if available (#13038) d53205076e is described below commit d53205076e3085ae16d98a33106797b62be140ea Author: morrySnow <101034200+morrys...@users.noreply.github.com> AuthorDate: Wed Sep 28 21:34:25 2022 +0800 [feature](Nereids) implicit cast StringLiteral to another side type of BinaryOperator if available (#13038) for expression 5 > '1'. before this PR, we normalize it to '5' > '1'. After this PR, we normalize it to 5 > 1 to compatible with legacy planner. --- .../doris/nereids/jobs/batch/TypeCoercionJob.java | 3 +- .../rewrite/ExpressionNormalization.java | 2 + .../rules/CharacterLiteralTypeCoercion.java | 129 +++++++++++++++++++++ .../nereids/trees/expressions/literal/Literal.java | 4 + 4 files changed, 137 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/TypeCoercionJob.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/TypeCoercionJob.java index 92dfa89c7e..49523e1352 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/TypeCoercionJob.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/TypeCoercionJob.java @@ -19,6 +19,7 @@ package org.apache.doris.nereids.jobs.batch; import org.apache.doris.nereids.CascadesContext; import org.apache.doris.nereids.rules.expression.rewrite.ExpressionNormalization; +import org.apache.doris.nereids.rules.expression.rewrite.rules.CharacterLiteralTypeCoercion; import org.apache.doris.nereids.rules.expression.rewrite.rules.TypeCoercion; import com.google.common.collect.ImmutableList; @@ -35,7 +36,7 @@ public class TypeCoercionJob extends BatchRulesJob { rulesJob.addAll(ImmutableList.of( topDownBatch(ImmutableList.of( new ExpressionNormalization(cascadesContext.getConnectContext(), - ImmutableList.of(TypeCoercion.INSTANCE))) + ImmutableList.of(CharacterLiteralTypeCoercion.INSTANCE, TypeCoercion.INSTANCE))) ))); } } 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 57d6b509d7..cf75610a62 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 @@ -18,6 +18,7 @@ package org.apache.doris.nereids.rules.expression.rewrite; import org.apache.doris.nereids.rules.expression.rewrite.rules.BetweenToCompoundRule; +import org.apache.doris.nereids.rules.expression.rewrite.rules.CharacterLiteralTypeCoercion; 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; @@ -41,6 +42,7 @@ public class ExpressionNormalization extends ExpressionRewrite { InPredicateToEqualToRule.INSTANCE, SimplifyNotExprRule.INSTANCE, SimplifyCastRule.INSTANCE, + CharacterLiteralTypeCoercion.INSTANCE, TypeCoercion.INSTANCE, FoldConstantRule.INSTANCE ); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/CharacterLiteralTypeCoercion.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/CharacterLiteralTypeCoercion.java new file mode 100644 index 0000000000..ff3ae1ffbc --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/CharacterLiteralTypeCoercion.java @@ -0,0 +1,129 @@ +// 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.BinaryOperator; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; +import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral; +import org.apache.doris.nereids.trees.expressions.literal.CharLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DecimalLiteral; +import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral; +import org.apache.doris.nereids.trees.expressions.literal.FloatLiteral; +import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; +import org.apache.doris.nereids.trees.expressions.literal.LargeIntLiteral; +import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral; +import org.apache.doris.nereids.trees.expressions.literal.StringLiteral; +import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral; +import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; +import org.apache.doris.nereids.types.BooleanType; +import org.apache.doris.nereids.types.CharType; +import org.apache.doris.nereids.types.DataType; +import org.apache.doris.nereids.types.DateTimeType; +import org.apache.doris.nereids.types.DateType; +import org.apache.doris.nereids.types.DecimalType; +import org.apache.doris.nereids.types.DoubleType; +import org.apache.doris.nereids.types.FloatType; +import org.apache.doris.nereids.types.StringType; +import org.apache.doris.nereids.types.VarcharType; +import org.apache.doris.nereids.types.coercion.IntegralType; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Optional; + +/** + * coercion character literal to another side + */ +public class CharacterLiteralTypeCoercion extends AbstractExpressionRewriteRule { + + public static final CharacterLiteralTypeCoercion INSTANCE = new CharacterLiteralTypeCoercion(); + + @Override + public Expression visitBinaryOperator(BinaryOperator binaryOperator, ExpressionRewriteContext context) { + Expression left = rewrite(binaryOperator.left(), context); + Expression right = rewrite(binaryOperator.right(), context); + if (!(left instanceof Literal) && !(right instanceof Literal)) { + return binaryOperator.withChildren(left, right); + } + if (left instanceof Literal && right instanceof Literal) { + // process by constant folding + return binaryOperator.withChildren(left, right); + } + if (left instanceof Literal && ((Literal) left).isCharacterLiteral()) { + left = characterLiteralTypeCoercion(((Literal) left).getStringValue(), right.getDataType()).orElse(left); + } + if (right instanceof Literal && ((Literal) right).isCharacterLiteral()) { + right = characterLiteralTypeCoercion(((Literal) right).getStringValue(), left.getDataType()).orElse(right); + + } + return binaryOperator.withChildren(left, right); + } + + private Optional<Expression> characterLiteralTypeCoercion(String value, DataType dataType) { + Expression ret = null; + try { + if (dataType instanceof BooleanType) { + if ("true".equalsIgnoreCase(value)) { + ret = BooleanLiteral.TRUE; + } + if ("false".equalsIgnoreCase(value)) { + ret = BooleanLiteral.FALSE; + } + } else if (dataType instanceof IntegralType) { + BigInteger bigInt = new BigInteger(value); + if (BigInteger.valueOf(bigInt.byteValue()).equals(bigInt)) { + ret = new TinyIntLiteral(bigInt.byteValue()); + } else if (BigInteger.valueOf(bigInt.shortValue()).equals(bigInt)) { + ret = new SmallIntLiteral(bigInt.shortValue()); + } else if (BigInteger.valueOf(bigInt.intValue()).equals(bigInt)) { + ret = new IntegerLiteral(bigInt.intValue()); + } else if (BigInteger.valueOf(bigInt.longValue()).equals(bigInt)) { + ret = new BigIntLiteral(bigInt.longValueExact()); + } else { + ret = new LargeIntLiteral(bigInt); + } + } else if (dataType instanceof FloatType) { + ret = new FloatLiteral(Float.parseFloat(value)); + } else if (dataType instanceof DoubleType) { + ret = new DoubleLiteral(Double.parseDouble(value)); + } else if (dataType instanceof DecimalType) { + ret = new DecimalLiteral(new BigDecimal(value)); + } else if (dataType instanceof CharType) { + ret = new CharLiteral(value, value.length()); + } else if (dataType instanceof VarcharType) { + ret = new VarcharLiteral(value, value.length()); + } else if (dataType instanceof StringType) { + ret = new StringLiteral(value); + } else if (dataType instanceof DateType) { + ret = new DateLiteral(value); + } else if (dataType instanceof DateTimeType) { + ret = new DateTimeLiteral(value); + } + } catch (Exception e) { + // ignore + } + return Optional.ofNullable(ret); + + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java index d88dbacac9..97f10e7335 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java @@ -189,6 +189,10 @@ public abstract class Literal extends Expression implements LeafExpression { throw new AnalysisException("no support cast!"); } + public boolean isCharacterLiteral() { + return this instanceof StringLiteral || this instanceof CharLiteral || this instanceof VarcharLiteral; + } + @Override public boolean equals(Object o) { if (this == o) { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org