diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java index 74ff1d809a..36895d8111 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java @@ -691,7 +691,10 @@ public class AnalyticExpr extends Expr { Type type = getFnCall().getChildren().get(2).getType(); try { - getFnCall().uncheckedCastChild(getFnCall().getChildren().get(0).getType(), 2); + if (!Type.matchExactType(getFnCall().getChildren().get(0).getType(), + getFnCall().getChildren().get(2).getType())) { + getFnCall().uncheckedCastChild(getFnCall().getChildren().get(0).getType(), 2); + } } catch (Exception e) { LOG.warn("", e); throw new AnalysisException("Convert type error in offset fn(default value); old_type=" diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java index 0c0a7e6346..2e32fc3ec0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java @@ -20,7 +20,6 @@ package org.apache.doris.analysis; -import org.apache.doris.catalog.ArrayType; import org.apache.doris.catalog.Env; import org.apache.doris.catalog.Function; import org.apache.doris.catalog.FunctionSet; @@ -269,24 +268,7 @@ public class CastExpr extends Expr { Type childType = getChild(0).getType(); // this cast may result in loss of precision, but the user requested it - if (childType.matchesType(type)) { - if (PrimitiveType.typeWithPrecision.contains(type.getPrimitiveType())) { - // For types which has precision and scale, we also need to check quality between precisions and scales - if ((((ScalarType) type).decimalPrecision() - == ((ScalarType) childType).decimalPrecision()) && (((ScalarType) type).decimalScale() - == ((ScalarType) childType).decimalScale())) { - noOp = true; - } - } else if (type.isArrayType()) { - // For types array, we also need to check contains null for case like - // cast(array as array) - if (((ArrayType) type).getContainsNull() == ((ArrayType) childType).getContainsNull()) { - noOp = true; - } - } else { - noOp = true; - } - } + noOp = Type.matchExactType(childType, type); if (noOp) { return; diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java index 257724038c..a832b853b6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java @@ -1637,4 +1637,27 @@ public abstract class Type { return this.getPrimitiveType().getOlapColumnIndexSize(); } } + + // Whether `type1` matches the exact type of `type2`. + public static boolean matchExactType(Type type1, Type type2) { + if (type1.matchesType(type2)) { + if (PrimitiveType.typeWithPrecision.contains(type2.getPrimitiveType())) { + // For types which has precision and scale, we also need to check quality between precisions and scales + if ((((ScalarType) type2).decimalPrecision() + == ((ScalarType) type1).decimalPrecision()) && (((ScalarType) type2).decimalScale() + == ((ScalarType) type1).decimalScale())) { + return true; + } + } else if (type2.isArrayType()) { + // For types array, we also need to check contains null for case like + // cast(array as array) + if (((ArrayType) type2).getContainsNull() == ((ArrayType) type1).getContainsNull()) { + return true; + } + } else { + return true; + } + } + return false; + } } diff --git a/regression-test/data/correctness_p0/test_lag_lead_window.out b/regression-test/data/correctness_p0/test_lag_lead_window.out index c2a4258c0b..97462cc8a2 100644 --- a/regression-test/data/correctness_p0/test_lag_lead_window.out +++ b/regression-test/data/correctness_p0/test_lag_lead_window.out @@ -19,3 +19,13 @@ a aa /wyyt-image/2021/11/13/595345040188712460.jpg b aa /wyyt-image/2022/04/13/1434607674511761493.jpg /wyyt-image/2022/04/13/1434607674511761493.jpg c cc /wyyt-image/2022/04/13/1434607674511761493.jpg +-- !select_default -- +c 2022-09-06T00:00:02 2022-09-06T00:00:01 +b 2022-09-06T00:00:01 2022-09-06T00:00 +a 2022-09-06T00:00 2022-09-06T00:00 + +-- !select_default -- +c 2022-09-06T00:00:02 2022-09-06T00:00:01 +b 2022-09-06T00:00:01 2022-09-06T00:00 +a 2022-09-06T00:00 2022-08-30T00:00 + diff --git a/regression-test/suites/correctness_p0/test_lag_lead_window.groovy b/regression-test/suites/correctness_p0/test_lag_lead_window.groovy index d269b1621d..44ccb66e14 100644 --- a/regression-test/suites/correctness_p0/test_lag_lead_window.groovy +++ b/regression-test/suites/correctness_p0/test_lag_lead_window.groovy @@ -54,4 +54,15 @@ suite("test_lag_lead_window") { lead(cc,1,'') over (PARTITION by cc order by aa) as lead_cc from ${tableName} order by aa; """ + sql """ DROP TABLE IF EXISTS test1 """ + sql """ CREATE TABLE IF NOT EXISTS test1 (id varchar(255), create_time datetime) + DISTRIBUTED BY HASH(id) PROPERTIES("replication_num" = "1"); """ + sql """ INSERT INTO test1 VALUES + ('a','2022-09-06 00:00:00'), + ('b','2022-09-06 00:00:01'), + ('c','2022-09-06 00:00:02') """ + qt_select_default """ select id, create_time, lead(create_time, 1, '2022-09-06 00:00:00') over + (order by create_time desc) as "prev_time" from test1; """ + qt_select_default """ select id, create_time, lead(create_time, 1, date_sub('2022-09-06 00:00:00', interval 7 day)) over (order by create_time desc) as "prev_time" from test1; """ + sql """ DROP TABLE IF EXISTS test1 """ }