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 7f84db310a [fix](nereids) Convert to datetime when binary expr's left is date and right is int type (#15615) 7f84db310a is described below commit 7f84db310a5f8310b5e308606efd6351a854bb9f Author: AKIRA <33112463+kikyou1...@users.noreply.github.com> AuthorDate: Fri Jan 6 14:08:05 2023 +0800 [fix](nereids) Convert to datetime when binary expr's left is date and right is int type (#15615) In the below case, expression ` date > 20200101` should implicit cast date both side to datetime instead of bigint ```sql CREATE TABLE `part_by_date` ( `date` date NOT NULL COMMENT '', `id` int(11) NOT NULL COMMENT '' ) ENGINE=OLAP UNIQUE KEY(`date`, `id`) PARTITION BY RANGE(`date`) (PARTITION p201912 VALUES [('0000-01-01'), ('2020-01-01')), PARTITION p202001 VALUES [('2020-01-01'), ('2020-02-01'))) DISTRIBUTED BY HASH(`id`) BUCKETS 3 PROPERTIES ( "replication_allocation" = "tag.location.default: 1" ); INSERT INTO part_by_date VALUES('0001-02-01', 1),('2020-01-15', 2); SELECT id FROM part_by_date WHERE date > 20200101; ``` --- .../expression/rewrite/rules/TypeCoercion.java | 14 +++--- .../trees/expressions/BinaryArithmetic.java | 3 +- .../trees/plans/logical/LogicalSetOperation.java | 2 +- .../doris/nereids/util/TypeCoercionUtils.java | 29 ++++++++++--- .../org/apache/doris/planner/OriginalPlanner.java | 2 - .../doris/nereids/util/TypeCoercionUtilsTest.java | 3 +- .../data/nereids_syntax_p0/test_convert.out | 4 ++ .../suites/nereids_syntax_p0/test_convert.groovy | 50 ++++++++++++++++++++++ 8 files changed, 90 insertions(+), 17 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java index a81aefc986..e1bb596a00 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rewrite/rules/TypeCoercion.java @@ -77,23 +77,23 @@ public class TypeCoercion extends AbstractExpressionRewriteRule { // TODO: add other expression visitor function to do type coercion if necessary. @Override - public Expression visitBinaryOperator(BinaryOperator binaryOperator, ExpressionRewriteContext context) { - Expression left = rewrite(binaryOperator.left(), context); - Expression right = rewrite(binaryOperator.right(), context); + public Expression visitBinaryOperator(BinaryOperator op, ExpressionRewriteContext context) { + Expression left = rewrite(op.left(), context); + Expression right = rewrite(op.right(), context); return Optional.of(TypeCoercionUtils.canHandleTypeCoercion(left.getDataType(), right.getDataType())) .filter(Boolean::booleanValue) - .map(b -> TypeCoercionUtils.findTightestCommonType(left.getDataType(), right.getDataType())) + .map(b -> TypeCoercionUtils.findTightestCommonType(op, left.getDataType(), right.getDataType())) .filter(Optional::isPresent) .map(Optional::get) - .filter(ct -> binaryOperator.inputType().acceptsType(ct)) + .filter(ct -> op.inputType().acceptsType(ct)) .filter(ct -> !left.getDataType().equals(ct) || !right.getDataType().equals(ct)) .map(commonType -> { Expression newLeft = TypeCoercionUtils.castIfNotSameType(left, commonType); Expression newRight = TypeCoercionUtils.castIfNotSameType(right, commonType); - return binaryOperator.withChildren(newLeft, newRight); + return op.withChildren(newLeft, newRight); }) - .orElse(binaryOperator.withChildren(left, right)); + .orElse(op.withChildren(left, right)); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryArithmetic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryArithmetic.java index ec45b4f707..942252ccaf 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryArithmetic.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/BinaryArithmetic.java @@ -48,7 +48,8 @@ public abstract class BinaryArithmetic extends BinaryOperator implements Propaga try { return TypeCoercionUtils.findCommonNumericsType(left().getDataType(), right().getDataType()); } catch (Exception e) { - return TypeCoercionUtils.findTightestCommonType(left().getDataType(), right().getDataType()) + return TypeCoercionUtils.findTightestCommonType(this, + left().getDataType(), right().getDataType()) .orElseGet(() -> left().getDataType()); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java index 10c5eb275c..1e69cda49c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSetOperation.java @@ -134,7 +134,7 @@ public abstract class LogicalSetOperation extends AbstractLogicalPlan implements Slot right = child(1).getOutput().get(i); if (TypeCoercionUtils.canHandleTypeCoercion(left.getDataType(), right.getDataType())) { Optional<DataType> tightestCommonType = - TypeCoercionUtils.findTightestCommonType(left.getDataType(), right.getDataType()); + TypeCoercionUtils.findTightestCommonType(null, left.getDataType(), right.getDataType()); if (tightestCommonType.isPresent()) { Expression newLeft = TypeCoercionUtils.castIfNotSameType(left, tightestCommonType.get()); Expression newRight = TypeCoercionUtils.castIfNotSameType(right, tightestCommonType.get()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java index ccb0796ae6..bc357e4fef 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java @@ -19,6 +19,8 @@ package org.apache.doris.nereids.util; import org.apache.doris.nereids.annotation.Developing; import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.nereids.trees.expressions.BinaryArithmetic; +import org.apache.doris.nereids.trees.expressions.BinaryOperator; import org.apache.doris.nereids.trees.expressions.Cast; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.literal.Literal; @@ -186,7 +188,8 @@ public class TypeCoercionUtils { * find the tightest common type for two type */ @Developing - public static Optional<DataType> findTightestCommonType(DataType left, DataType right) { + public static Optional<DataType> findTightestCommonType(BinaryOperator binaryOperator, + DataType left, DataType right) { // TODO: compatible with origin planner and BE // TODO: when add new type, add it to here DataType tightestCommonType = null; @@ -234,9 +237,12 @@ public class TypeCoercionUtils { } else if (left instanceof DateV2Type || right instanceof DateV2Type) { tightestCommonType = DateV2Type.INSTANCE; } - } else if ((left instanceof DateLikeType && right instanceof IntegralType) - || (right instanceof DateLikeType && left instanceof IntegralType)) { - tightestCommonType = BigIntType.INSTANCE; + } else if (canCompareDate(left, right)) { + if (binaryOperator instanceof BinaryArithmetic) { + tightestCommonType = IntegerType.INSTANCE; + } else { + tightestCommonType = DateTimeType.INSTANCE; + } } return tightestCommonType == null ? Optional.of(DoubleType.INSTANCE) : Optional.of(tightestCommonType); } @@ -302,7 +308,7 @@ public class TypeCoercionUtils { // TODO: need to rethink how to handle char and varchar to return char or varchar as much as possible. return Stream .<Supplier<Optional<DataType>>>of( - () -> findTightestCommonType(left, right), + () -> findTightestCommonType(null, left, right), () -> findWiderTypeForDecimal(left, right), () -> characterPromotion(left, right), () -> findTypeForComplex(left, right)) @@ -381,4 +387,17 @@ public class TypeCoercionUtils { return new Cast(input, dataType); } } + + private static boolean canCompareDate(DataType left, DataType right) { + if (left instanceof DateLikeType) { + return right.isDateType() || right.isStringType() || right instanceof TinyIntType + || right instanceof SmallIntType || right instanceof IntegerType + || right instanceof BigIntType; + } else if (right instanceof DateLikeType) { + return left.isStringType() || left instanceof TinyIntType + || left instanceof SmallIntType || left instanceof IntegerType + || left instanceof BigIntType; + } + return false; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java b/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java index d882c65119..c2c15c5c31 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java @@ -91,8 +91,6 @@ public class OriginalPlanner extends Planner { return analyzer.getAssignedRuntimeFilter(); } - /** - */ private void setResultExprScale(Analyzer analyzer, ArrayList<Expr> outputExprs) { for (TupleDescriptor tupleDesc : analyzer.getDescTbl().getTupleDescs()) { for (SlotDescriptor slotDesc : tupleDesc.getSlots()) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/TypeCoercionUtilsTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/TypeCoercionUtilsTest.java index bbd75d48c2..16ac52b8ec 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/TypeCoercionUtilsTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/TypeCoercionUtilsTest.java @@ -155,7 +155,8 @@ public class TypeCoercionUtilsTest { } private void testFindTightestCommonType(DataType commonType, DataType left, DataType right) { - Assertions.assertEquals(Optional.ofNullable(commonType), TypeCoercionUtils.findTightestCommonType(left, right)); + Assertions.assertEquals(Optional.ofNullable(commonType), TypeCoercionUtils.findTightestCommonType(null, + left, right)); } @Test diff --git a/regression-test/data/nereids_syntax_p0/test_convert.out b/regression-test/data/nereids_syntax_p0/test_convert.out new file mode 100644 index 0000000000..4ee136aef2 --- /dev/null +++ b/regression-test/data/nereids_syntax_p0/test_convert.out @@ -0,0 +1,4 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !sql -- +2 + diff --git a/regression-test/suites/nereids_syntax_p0/test_convert.groovy b/regression-test/suites/nereids_syntax_p0/test_convert.groovy new file mode 100644 index 0000000000..9f402c4a7e --- /dev/null +++ b/regression-test/suites/nereids_syntax_p0/test_convert.groovy @@ -0,0 +1,50 @@ +// 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. + +suite("test_implicit_convert") { + + sql """ + DROP TABLE IF EXISTS part_by_date + """ + sql """ + CREATE TABLE `part_by_date` + ( + `date` date NOT NULL COMMENT '', + `id` int(11) NOT NULL COMMENT '' + ) ENGINE=OLAP + UNIQUE KEY(`date`, `id`) + PARTITION BY RANGE(`date`) + (PARTITION p201912 VALUES [('0000-01-01'), ('2020-01-01')), + PARTITION p202001 VALUES [('2020-01-01'), ('2020-02-01'))) + DISTRIBUTED BY HASH(`id`) BUCKETS 3 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + """ + + sql """ + INSERT INTO part_by_date VALUES('0001-02-01', 1),('2020-01-15', 2); + """ + + qt_sql """ + SELECT + id + FROM + part_by_date + WHERE date > 20200101; + """ +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org