This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new b752bdc4281 branch-3.1: [fix](nereids)fold constant rule can't fold
from_unixtime when its 1st param is decimalv3 literal #57363 (#57606)
b752bdc4281 is described below
commit b752bdc4281a1617dcac08650d7f23ba8f271b42
Author: starocean999 <[email protected]>
AuthorDate: Mon Nov 10 14:18:52 2025 +0800
branch-3.1: [fix](nereids)fold constant rule can't fold from_unixtime when
its 1st param is decimalv3 literal #57363 (#57606)
picked from #57363
---
.../executable/DateTimeExtractAndTransform.java | 51 ++++++++++++++++++++++
.../trees/expressions/literal/DateTimeLiteral.java | 2 +-
.../expressions/literal/DateTimeV2Literal.java | 4 ++
.../org/apache/doris/nereids/util/DateUtils.java | 4 +-
.../DateTimeExtractAndTransformTest.java | 19 ++++++++
5 files changed, 78 insertions(+), 2 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 fda880d8dd4..f12985b3ffd 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
@@ -32,6 +32,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.DecimalLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal;
import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
@@ -537,6 +538,16 @@ public class DateTimeExtractAndTransform {
return fromUnixTime(second, new VarcharLiteral("%Y-%m-%d %H:%i:%s"));
}
+ @ExecFunction(name = "from_unixtime")
+ public static Expression fromUnixTime(DecimalLiteral second) {
+ return fromUnixTime(second, new VarcharLiteral("%Y-%m-%d
%H:%i:%s.%f"));
+ }
+
+ @ExecFunction(name = "from_unixtime")
+ public static Expression fromUnixTime(DecimalV3Literal second) {
+ return fromUnixTime(second, new VarcharLiteral("%Y-%m-%d
%H:%i:%s.%f"));
+ }
+
/**
* date transformation function: from_unixtime
*/
@@ -559,6 +570,46 @@ public class DateTimeExtractAndTransform {
format);
}
+ /**
+ * date transformation function: from_unixtime
+ */
+ @ExecFunction(name = "from_unixtime")
+ public static Expression fromUnixTime(DecimalLiteral second,
StringLikeLiteral format) {
+ BigDecimal val = second.getValue();
+ return fromUnixTime(val, format);
+ }
+
+ /**
+ * date transformation function: from_unixtime
+ */
+ @ExecFunction(name = "from_unixtime")
+ public static Expression fromUnixTime(DecimalV3Literal second,
StringLikeLiteral format) {
+ BigDecimal val = second.getValue();
+ return fromUnixTime(val, format);
+ }
+
+ private static Expression fromUnixTime(BigDecimal second,
StringLikeLiteral format) {
+ // 32536771199L is max valid timestamp of mysql from_unix_time
+ if (second.signum() < 0 || second.longValue() > 32536771199L) {
+ return new NullLiteral(VarcharType.SYSTEM_DEFAULT);
+ }
+ format = (StringLikeLiteral)
SupportJavaDateFormatter.translateJavaFormatter(format);
+ BigDecimal microSeconds =
second.movePointRight(second.scale()).setScale(0, RoundingMode.DOWN);
+ ZonedDateTime dateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0)
+ .plus(microSeconds.longValue(), ChronoUnit.MICROS)
+ .atZone(ZoneId.of("UTC+0"))
+ .toOffsetDateTime()
+ .atZoneSameInstant(DateUtils.getTimeZone());
+ DateTimeV2Literal datetime = new
DateTimeV2Literal(DateTimeV2Type.of(6), dateTime.getYear(),
+ dateTime.getMonthValue(),
+ dateTime.getDayOfMonth(), dateTime.getHour(),
dateTime.getMinute(), dateTime.getSecond(),
+ dateTime.getNano() / 1000);
+ if (datetime.checkRange()) {
+ throw new AnalysisException("Operation from_unixtime of " + second
+ " out of range");
+ }
+ return dateFormat(datetime, format);
+ }
+
/**
* date transformation function: unix_timestamp
*/
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
index 7912142f97f..67659b0ac2f 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteral.java
@@ -245,7 +245,7 @@ public class DateTimeLiteral extends DateLiteral {
}
}
- protected boolean checkRange() {
+ public boolean checkRange() {
return checkRange(year, month, day) || hour > MAX_DATETIME.getHour()
|| minute > MAX_DATETIME.getMinute()
|| second > MAX_DATETIME.getSecond() || microSecond >
MAX_MICROSECOND;
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java
index 599e903df39..759c83c031b 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java
@@ -91,6 +91,10 @@ public class DateTimeV2Literal extends DateTimeLiteral {
year, month, day, hour, minute, second, microSecond);
}
+ public int getScale() {
+ return ((DateTimeV2Type) dataType).getScale();
+ }
+
@Override
public DateTimeV2Type getDataType() throws UnboundException {
return (DateTimeV2Type) super.getDataType();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java
index 047b8d43e10..e928e2839d2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java
@@ -139,9 +139,11 @@ public class DateUtils {
case 'y': // %y Year, numeric (two digits)
builder.appendValueReduced(ChronoField.YEAR, 2, 2,
1970);
break;
+ case 'f':
+ builder.appendValue(ChronoField.MICRO_OF_SECOND, 6);
+ break;
// TODO(Gabriel): support microseconds in date literal
case 'D': // %D Day of the month with English suffix (0th,
1st, 2nd, 3rd, …)
- case 'f': // %f Microseconds (000000..999999)
case 'U': // %U Week (00..53), where Sunday is the first
day of the week
case 'u': // %u Week (00..53), where Monday is the first
day of the week
case 'w': // %w Day of the week (0=Sunday..6=Saturday)
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransformTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransformTest.java
index c6289a45f9f..5a49be3594d 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransformTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransformTest.java
@@ -19,14 +19,18 @@ package
org.apache.doris.nereids.trees.expressions.functions.executable;
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
+import org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal;
+import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
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.types.DateTimeV2Type;
+import org.apache.doris.nereids.types.VarcharType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.math.BigDecimal;
import java.time.LocalDateTime;
class DateTimeExtractAndTransformTest {
@@ -148,4 +152,19 @@ class DateTimeExtractAndTransformTest {
result = (DateTimeV2Literal)
DateTimeExtractAndTransform.fromMicroSecond(second);
Assertions.assertEquals(6, result.getDataType().getScale());
}
+
+ @Test
+ public void testFromUnixTimeNegative() {
+ BigIntLiteral negative = new BigIntLiteral(-1L);
+ Assertions.assertEquals(new NullLiteral(VarcharType.SYSTEM_DEFAULT),
+ DateTimeExtractAndTransform.fromUnixTime(negative));
+ }
+
+ @Test
+ public void testFromUnixTimeOutOfRange() {
+ BigDecimal big = new BigDecimal("253402272000000000");
+ DecimalV3Literal dec = new DecimalV3Literal(big);
+ Assertions.assertEquals(new NullLiteral(VarcharType.SYSTEM_DEFAULT),
+ DateTimeExtractAndTransform.fromUnixTime(dec));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]