This is an automated email from the ASF dual-hosted git repository. yiguolei 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 f4d029dba03 [fix](Nereids) unix_timestamp compute signature and fold const is wrong (#35727) f4d029dba03 is described below commit f4d029dba03622eea87f136c5d75380a3c7c015a Author: morrySnow <101034200+morrys...@users.noreply.github.com> AuthorDate: Mon Jun 3 18:56:11 2024 +0800 [fix](Nereids) unix_timestamp compute signature and fold const is wrong (#35727) 1. compute signature should call super#computeSignature first 2. fold const return type not changed after signature changed in #26827 we already have p0 for this case, but our regression framework has bug that it report success when compare decimal type if real result lose scale --- .../executable/DateTimeExtractAndTransform.java | 29 ++++++---- .../functions/scalar/UnixTimestamp.java | 5 +- .../nereids/rules/expression/FoldConstantTest.java | 66 ++++++++++------------ 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java index 3cc46ee1114..e7a92354440 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java @@ -493,17 +493,17 @@ public class DateTimeExtractAndTransform { */ @ExecFunction(name = "unix_timestamp", argTypes = {"DATE"}, returnType = "INT") public static Expression unixTimestamp(DateLiteral date) { - return new IntegerLiteral(getTimestamp(date.toJavaDateType())); + return new IntegerLiteral(Integer.parseInt(getTimestamp(date.toJavaDateType()))); } @ExecFunction(name = "unix_timestamp", argTypes = {"DATETIME"}, returnType = "INT") public static Expression unixTimestamp(DateTimeLiteral date) { - return new IntegerLiteral(getTimestamp(date.toJavaDateType())); + return new IntegerLiteral(Integer.parseInt(getTimestamp(date.toJavaDateType()))); } @ExecFunction(name = "unix_timestamp", argTypes = {"DATEV2"}, returnType = "INT") public static Expression unixTimestamp(DateV2Literal date) { - return new IntegerLiteral(getTimestamp(date.toJavaDateType())); + return new IntegerLiteral(Integer.parseInt(getTimestamp(date.toJavaDateType()))); } /** @@ -513,18 +513,17 @@ public class DateTimeExtractAndTransform { public static Expression unixTimestamp(DateTimeV2Literal date) { if (date.getMicroSecond() == 0) { return new DecimalV3Literal(DecimalV3Type.createDecimalV3TypeLooseCheck(10, 0), - new BigDecimal(getTimestamp(date.toJavaDateType()).toString())); + new BigDecimal(getTimestamp(date.toJavaDateType()))); } int scale = date.getDataType().getScale(); - String val = getTimestamp(date.toJavaDateType()).toString() + "." + date.getMicrosecondString(); return new DecimalV3Literal(DecimalV3Type.createDecimalV3TypeLooseCheck(10 + scale, scale), - new BigDecimal(val)); + new BigDecimal(getTimestamp(date.toJavaDateType()))); } /** * date transformation function: unix_timestamp */ - @ExecFunction(name = "unix_timestamp", argTypes = {"VARCHAR", "VARCHAR"}, returnType = "INT") + @ExecFunction(name = "unix_timestamp", argTypes = {"VARCHAR", "VARCHAR"}, returnType = "DECIMALV3") public static Expression unixTimestamp(StringLikeLiteral date, StringLikeLiteral format) { DateTimeFormatter formatter = DateUtils.formatBuilder(format.getValue()).toFormatter(); LocalDateTime dateObj; @@ -534,20 +533,26 @@ public class DateTimeExtractAndTransform { // means the date string doesn't contain time fields. dateObj = LocalDate.parse(date.getValue(), formatter).atStartOfDay(); } - return new IntegerLiteral(getTimestamp(dateObj)); + return new DecimalV3Literal(DecimalV3Type.createDecimalV3TypeLooseCheck(16, 6), + new BigDecimal(getTimestamp(dateObj))); } - private static Integer getTimestamp(LocalDateTime dateTime) { + private static String getTimestamp(LocalDateTime dateTime) { LocalDateTime specialUpperBound = LocalDateTime.of(2038, 1, 19, 3, 14, 7); LocalDateTime specialLowerBound = LocalDateTime.of(1970, 1, 1, 0, 0, 0); if (dateTime.isBefore(specialLowerBound) || dateTime.isAfter(specialUpperBound)) { - return 0; + return "0"; } - return ((int) Duration.between( + Duration duration = Duration.between( specialLowerBound, dateTime.atZone(DateUtils.getTimeZone()) .toOffsetDateTime().atZoneSameInstant(ZoneId.of("UTC+0")) - .toLocalDateTime()).getSeconds()); + .toLocalDateTime()); + if (duration.getNano() == 0) { + return String.valueOf(duration.getSeconds()); + } else { + return duration.getSeconds() + "." + (duration.getNano() / 1000); + } } /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java index 9166dddf033..143bc63aade 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java @@ -46,7 +46,7 @@ public class UnixTimestamp extends ScalarFunction // we got changes when computeSignature private static final List<FunctionSignature> SIGNATURES = ImmutableList.of( FunctionSignature.ret(IntegerType.INSTANCE).args(), - FunctionSignature.ret(DecimalV3Type.createDecimalV3Type(16, 6)).args(DateTimeV2Type.SYSTEM_DEFAULT), + FunctionSignature.ret(DecimalV3Type.WILDCARD).args(DateTimeV2Type.SYSTEM_DEFAULT), FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE), FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeType.INSTANCE), FunctionSignature.ret(IntegerType.INSTANCE).args(DateType.INSTANCE), @@ -102,6 +102,7 @@ public class UnixTimestamp extends ScalarFunction @Override public FunctionSignature computeSignature(FunctionSignature signature) { + signature = super.computeSignature(signature); if (arity() != 1) { return signature; } @@ -120,7 +121,7 @@ public class UnixTimestamp extends ScalarFunction */ @Override public UnixTimestamp withChildren(List<Expression> children) { - Preconditions.checkArgument(children.size() == 0 + Preconditions.checkArgument(children.isEmpty() || children.size() == 1 || children.size() == 2); if (children.isEmpty() && arity() == 0) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java index 7a271314691..6e8d7aea8ed 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java @@ -43,6 +43,7 @@ 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.DateTimeV2Literal; import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal; +import org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal; import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; import org.apache.doris.nereids.trees.expressions.literal.Interval.TimeUnit; import org.apache.doris.nereids.trees.expressions.literal.Literal; @@ -60,6 +61,7 @@ import com.google.common.collect.ImmutableList; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Locale; @@ -183,65 +185,57 @@ class FoldConstantTest extends ExpressionRewriteTestHelper { ConvertTz c = new ConvertTz(DateTimeV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("Asia/Shanghai"), StringLiteral.of("GMT")); Expression rewritten = executor.rewrite(c, context); - String res = "0000-12-31 16:55:18"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new DateTimeV2Literal("0000-12-31 16:55:18"), rewritten); DateFormat d = new DateFormat(DateTimeLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("%y %m %d")); rewritten = executor.rewrite(d, context); - res = "'01 01 01'"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new VarcharLiteral("01 01 01"), rewritten); d = new DateFormat(DateTimeV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("%y %m %d")); rewritten = executor.rewrite(d, context); - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new VarcharLiteral("01 01 01"), rewritten); d = new DateFormat(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("%y %m %d")); rewritten = executor.rewrite(d, context); - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new VarcharLiteral("01 01 01"), rewritten); d = new DateFormat(DateV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("%y %m %d")); rewritten = executor.rewrite(d, context); - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new VarcharLiteral("01 01 01"), rewritten); DateTrunc t = new DateTrunc(DateTimeLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("week")); rewritten = executor.rewrite(t, context); - res = "0001-01-01 00:00:00"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new DateTimeLiteral("0001-01-01 00:00:00"), rewritten); t = new DateTrunc(DateTimeV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("week")); rewritten = executor.rewrite(t, context); - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new DateTimeV2Literal("0001-01-01 00:00:00"), rewritten); t = new DateTrunc(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("week")); rewritten = executor.rewrite(t, context); - res = "0001-01-01"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new DateLiteral("0001-01-01"), rewritten); t = new DateTrunc(DateV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)), StringLiteral.of("week")); rewritten = executor.rewrite(t, context); - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new DateV2Literal("0001-01-01"), rewritten); FromUnixtime f = new FromUnixtime(BigIntLiteral.of(123456789L), StringLiteral.of("%y %m %d")); rewritten = executor.rewrite(f, context); - res = "'73 11 30'"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new VarcharLiteral("73 11 30"), rewritten); UnixTimestamp ut = new UnixTimestamp(StringLiteral.of("2021-11-11"), StringLiteral.of("%Y-%m-%d")); rewritten = executor.rewrite(ut, context); - res = "1636560000"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new DecimalV3Literal(new BigDecimal("1636560000.000000")), rewritten); StrToDate sd = new StrToDate(StringLiteral.of("2021-11-11"), StringLiteral.of("%Y-%m-%d")); rewritten = executor.rewrite(sd, context); - res = "2021-11-11"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new DateV2Literal("2021-11-11"), rewritten); AppendTrailingCharIfAbsent a = new AppendTrailingCharIfAbsent(StringLiteral.of("1"), StringLiteral.of("3")); rewritten = executor.rewrite(a, context); - res = "'13'"; - Assertions.assertEquals(rewritten.toString(), res); + Assertions.assertEquals(new StringLiteral("13"), rewritten); } @Test @@ -659,34 +653,34 @@ class FoldConstantTest extends ExpressionRewriteTestHelper { void testDateConstructFunction() { String[] answer = { "'2001-07-19'", "'6411-08-17'", "'0000-01-01'", "'1977-06-03 17:57:24'", - "'1977-06-03'", "1008909293", "1008864000" + "'1977-06-03'", "1008909293", "1008864000.000000" }; int answerIdx = 0; - Assertions.assertEquals(DateTimeExtractAndTransform.makeDate( + Assertions.assertEquals(answer[answerIdx++], DateTimeExtractAndTransform.makeDate( new IntegerLiteral(2001), new IntegerLiteral(200) - ).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.fromDays( + ).toSql()); + Assertions.assertEquals(answer[answerIdx++], DateTimeExtractAndTransform.fromDays( new IntegerLiteral(2341798) - ).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.fromDays( + ).toSql()); + Assertions.assertEquals(answer[answerIdx++], DateTimeExtractAndTransform.fromDays( new IntegerLiteral(1) - ).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.fromUnixTime( + ).toSql()); + Assertions.assertEquals(answer[answerIdx++], DateTimeExtractAndTransform.fromUnixTime( new BigIntLiteral(234179844) - ).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.fromUnixTime( + ).toSql()); + Assertions.assertEquals(answer[answerIdx++], DateTimeExtractAndTransform.fromUnixTime( new BigIntLiteral(234179844), new VarcharLiteral("%Y-%m-%d") - ).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.unixTimestamp( + ).toSql()); + Assertions.assertEquals(answer[answerIdx++], DateTimeExtractAndTransform.unixTimestamp( new DateTimeLiteral("2001-12-21 12:34:53") - ).toSql(), answer[answerIdx++]); - Assertions.assertEquals(DateTimeExtractAndTransform.unixTimestamp( + ).toSql()); + Assertions.assertEquals(answer[answerIdx], DateTimeExtractAndTransform.unixTimestamp( new VarcharLiteral("2001-12-21"), new VarcharLiteral("%Y-%m-%d") - ).toSql(), answer[answerIdx]); + ).toSql()); } @Test --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org