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]

Reply via email to