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 74c0677d62 [fix](planner) fix bugs in uncheckedCastChild (#15905) 74c0677d62 is described below commit 74c0677d623340111f4fa918352f7ec00227d447 Author: minghong <engle...@gmail.com> AuthorDate: Thu Jan 19 15:51:08 2023 +0800 [fix](planner) fix bugs in uncheckedCastChild (#15905) 1. `uncheckedCastChild` may generate redundant `CastExpr` like `cast( cast(XXX as Date) as Date)` 2. generate DateLiteral to replace cast(IntLiteral as Date) --- .../main/java/org/apache/doris/catalog/Type.java | 7 ++++ .../main/java/org/apache/doris/analysis/Expr.java | 7 +++- .../java/org/apache/doris/analysis/IntLiteral.java | 47 ++++++++++++++-------- .../java/org/apache/doris/analysis/ExprTest.java | 10 +++++ .../org/apache/doris/analysis/InsertStmtTest.java | 5 ++- .../org/apache/doris/analysis/IntLiteralTest.java | 35 ++++++++++++++++ 6 files changed, 90 insertions(+), 21 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java index c94552d1f2..0fb6a779b6 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java @@ -283,6 +283,13 @@ public abstract class Type { return isScalarType(PrimitiveType.DATETIMEV2); } + public boolean isDateLike() { + return isScalarType(PrimitiveType.DATETIME) + || isScalarType(PrimitiveType.DATETIMEV2) + || isScalarType(PrimitiveType.DATE) + || isScalarType(PrimitiveType.DATEV2); + } + public boolean isTimeV2() { return isScalarType(PrimitiveType.TIMEV2); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java index 35bd80e9a3..50194d22ce 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java @@ -1448,8 +1448,11 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl public void uncheckedCastChild(Type targetType, int childIndex) throws AnalysisException { Expr child = getChild(childIndex); - Expr newChild = child.uncheckedCastTo(targetType); - setChild(childIndex, newChild); + //avoid to generate Expr like cast (cast(... as date) as date) + if (!child.getType().equals(targetType)) { + Expr newChild = child.uncheckedCastTo(targetType); + setChild(childIndex, newChild); + } } /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java index 0d3749fa86..8933ec496e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java @@ -294,28 +294,41 @@ public class IntLiteral extends LiteralExpr { @Override protected Expr uncheckedCastTo(Type targetType) throws AnalysisException { - if (!targetType.isNumericType()) { - return super.uncheckedCastTo(targetType); - } - if (targetType.isFixedPointType()) { - if (!targetType.isScalarType(PrimitiveType.LARGEINT)) { - if (!type.equals(targetType)) { - IntLiteral intLiteral = new IntLiteral(this); - intLiteral.setType(targetType); - return intLiteral; + if (targetType.isNumericType()) { + if (targetType.isFixedPointType()) { + if (!targetType.isScalarType(PrimitiveType.LARGEINT)) { + if (!type.equals(targetType)) { + IntLiteral intLiteral = new IntLiteral(this); + intLiteral.setType(targetType); + return intLiteral; + } + return this; + } else { + return new LargeIntLiteral(Long.toString(value)); } - return this; - } else { - return new LargeIntLiteral(Long.toString(value)); + } else if (targetType.isFloatingPointType()) { + return new FloatLiteral(new Double(value), targetType); + } else if (targetType.isDecimalV2() || targetType.isDecimalV3()) { + DecimalLiteral res = new DecimalLiteral(new BigDecimal(value)); + res.setType(targetType); + return res; + } + return this; + } else if (targetType.isDateLike()) { + try { + //int like 20200101 can be cast to date(2020,01,01) + DateLiteral res = new DateLiteral("" + value, targetType); + res.setType(targetType); + return res; + } catch (AnalysisException e) { + //invalid date format. leave it to BE to cast it as NULL } - } else if (targetType.isFloatingPointType()) { - return new FloatLiteral(new Double(value), targetType); - } else if (targetType.isDecimalV2() || targetType.isDecimalV3()) { - DecimalLiteral res = new DecimalLiteral(new BigDecimal(value)); + } else if (targetType.isStringType()) { + StringLiteral res = new StringLiteral("" + value); res.setType(targetType); return res; } - return this; + return super.uncheckedCastTo(targetType); } @Override diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java index ad4a3c21d6..475d9dc8fb 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/ExprTest.java @@ -32,6 +32,7 @@ import mockit.Injectable; import mockit.Mocked; import org.junit.Assert; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -202,6 +203,15 @@ public class ExprTest { Assert.assertFalse(Expr.equalSets(list1, list2)); } + @Test + public void testUncheckedCastChildAvoidDoubleCast() throws AnalysisException { + Expr cast = new CastExpr(Type.DATETIME, new IntLiteral(10000101)); + FunctionCallExpr call = new FunctionCallExpr("leap", Lists.newArrayList(cast)); + call.uncheckedCastChild(Type.DATETIME, 0); + //do not cast a castExpr + Assertions.assertTrue(call.getChild(0).getChild(0) instanceof IntLiteral); + } + @Test public void testSrcSlotRef(@Injectable SlotDescriptor slotDescriptor) { TableName tableName = new TableName(internalCtl, "db1", "table1"); diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java index b16abaf470..0b19e54f51 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/InsertStmtTest.java @@ -202,9 +202,10 @@ public class InsertStmtTest { FunctionCallExpr expr4 = (FunctionCallExpr) queryStmtSubstitute.getResultExprs().get(4); Assert.assertEquals(expr4.getFnName().getFunction(), "to_bitmap"); List<Expr> slots = Lists.newArrayList(); - expr4.collect(IntLiteral.class, slots); + expr4.collect(StringLiteral.class, slots); Assert.assertEquals(1, slots.size()); - Assert.assertEquals(queryStmtSubstitute.getResultExprs().get(0), slots.get(0)); + Assert.assertEquals(queryStmtSubstitute.getResultExprs().get(0).getStringValue(), + slots.get(0).getStringValue()); Assert.assertTrue(queryStmtSubstitute.getResultExprs().get(5) instanceof FunctionCallExpr); FunctionCallExpr expr5 = (FunctionCallExpr) queryStmtSubstitute.getResultExprs().get(5); diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/IntLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/IntLiteralTest.java new file mode 100644 index 0000000000..a3c9b48282 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/IntLiteralTest.java @@ -0,0 +1,35 @@ +// 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.analysis; + +import org.apache.doris.catalog.Type; +import org.apache.doris.common.AnalysisException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class IntLiteralTest { + @Test + public void testUncheckedCastTo() throws AnalysisException { + IntLiteral intLiteral = new IntLiteral(20200101); + Expr expr = intLiteral.uncheckedCastTo(Type.DATETIME); + Assertions.assertTrue(expr instanceof DateLiteral); + expr = intLiteral.uncheckedCastTo(Type.STRING); + Assertions.assertTrue(expr instanceof StringLiteral); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org