This is an automated email from the ASF dual-hosted git repository.

XiaoHongbo-Hope pushed a commit to branch release-2.1
in repository https://gitbox.apache.org/repos/asf/paimon.git

commit 880fb02af0d0e269ce7a4d96547699133f9e12c3
Author: jackylee <[email protected]>
AuthorDate: Tue Sep 15 11:17:01 2026 +0800

    [vortex] Do not push nanosecond timestamp literals that overflow int64 
(#9810)
---
 .../format/vortex/VortexPredicateConverter.java     | 18 ++++++++++++++----
 .../format/vortex/VortexPredicateConverterTest.java | 21 +++++++++++++++++++++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git 
a/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
 
b/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
index a4ec47aba5..baf315e86b 100644
--- 
a/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
+++ 
b/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
@@ -205,10 +205,20 @@ public class VortexPredicateConverter implements 
PredicateVisitor<Expression> {
                     Expression.TimeUnit.MICROSECONDS,
                     timeZone);
         } else {
-            return Expression.literalTimestamp(
-                    ts.getMillisecond() * 1_000_000 + 
ts.getNanoOfMillisecond(),
-                    Expression.TimeUnit.NANOSECONDS,
-                    timeZone);
+            // A TIMESTAMP value reaches year 9999, so nanoseconds since the 
epoch are not
+            // representable as an int64 outside roughly [1677-09-21, 
2262-04-11]. A wrapped bound
+            // silently excludes matching rows, so refuse to push the literal 
down for the same
+            // reason as the grain checks above.
+            long nanos;
+            try {
+                nanos =
+                        Math.addExact(
+                                Math.multiplyExact(ts.getMillisecond(), 
1_000_000L),
+                                ts.getNanoOfMillisecond());
+            } catch (ArithmeticException e) {
+                return null;
+            }
+            return Expression.literalTimestamp(nanos, 
Expression.TimeUnit.NANOSECONDS, timeZone);
         }
     }
 }
diff --git 
a/paimon-vortex/paimon-vortex-format/src/test/java/org/apache/paimon/format/vortex/VortexPredicateConverterTest.java
 
b/paimon-vortex/paimon-vortex-format/src/test/java/org/apache/paimon/format/vortex/VortexPredicateConverterTest.java
index 63b2099a57..222e6bd0ce 100644
--- 
a/paimon-vortex/paimon-vortex-format/src/test/java/org/apache/paimon/format/vortex/VortexPredicateConverterTest.java
+++ 
b/paimon-vortex/paimon-vortex-format/src/test/java/org/apache/paimon/format/vortex/VortexPredicateConverterTest.java
@@ -494,6 +494,27 @@ public class VortexPredicateConverterTest {
         assertEquals(1_500L, rows.get(0).getTimestamp(0, 0).getMillisecond());
     }
 
+    @Test
+    public void testTimestampNanosOverflowingLiteralNotPushed(@TempDir 
java.nio.file.Path tempDir)
+            throws Exception {
+        // epoch millis times 1_000_000 overflows int64 nanoseconds beyond 
2262-04-11, and the
+        // wrapped bound landed before the epoch, so "< 9999-12-31" dropped 
the epoch row
+        RowType tsRowType = RowType.builder().field("f_ts", 
DataTypes.TIMESTAMP(9)).build();
+        PredicateBuilder tsBuilder = new PredicateBuilder(tsRowType);
+        List<Predicate> predicates =
+                Collections.singletonList(
+                        tsBuilder.lessThan(0, 
Timestamp.fromEpochMillis(253402214400000L)));
+        assertNull(VortexPredicateConverter.toVortexExpression(predicates));
+        List<InternalRow> rows =
+                roundTrip(
+                        tempDir,
+                        tsRowType,
+                        new GenericRow[] 
{GenericRow.of(Timestamp.fromEpochMillis(0L))},
+                        predicates);
+        assertEquals(1, rows.size());
+        assertEquals(0L, rows.get(0).getTimestamp(0, 0).getMillisecond());
+    }
+
     private List<InternalRow> roundTrip(
             java.nio.file.Path tempDir,
             RowType rowType,

Reply via email to