This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 552ad0f182 [iceberg] Fix TIMESTAMP(3) bound decoding in
IcebergConversions (#8231)
552ad0f182 is described below
commit 552ad0f1825b56b5f5967be71b52e885f2b4e6ec
Author: Mo Ghazal <[email protected]>
AuthorDate: Sun Jun 14 13:24:26 2026 +0200
[iceberg] Fix TIMESTAMP(3) bound decoding in IcebergConversions (#8231)
`IcebergConversions.timestampFromBytes` decoded the manifest INT64 bound
with `Timestamp.fromEpochMillis` for `precision == 3`, but the Iceberg
manifest always stores timestamps as INT64 **microseconds** regardless
of precision. For precision 4–6 the same method already used
`Timestamp.fromMicros` correctly, making the precision-3 branch
inconsistent.
The practical consequence is that reading a precision-3 timestamp bound
back from a manifest returns a value 1000× too large, and if that
inflated value is subsequently passed through `Timestamp.toMicros()` it
causes `ArithmeticException: long overflow` in `Math.multiplyExact`.
---
.../java/org/apache/paimon/iceberg/manifest/IcebergConversions.java | 2 +-
.../paimon/iceberg/manifest/IcebergConversionsTimestampTest.java | 5 ++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git
a/paimon-core/src/main/java/org/apache/paimon/iceberg/manifest/IcebergConversions.java
b/paimon-core/src/main/java/org/apache/paimon/iceberg/manifest/IcebergConversions.java
index 02c1ab8368..194581f30a 100644
---
a/paimon-core/src/main/java/org/apache/paimon/iceberg/manifest/IcebergConversions.java
+++
b/paimon-core/src/main/java/org/apache/paimon/iceberg/manifest/IcebergConversions.java
@@ -131,7 +131,7 @@ public class IcebergConversions {
precision >= 3 && precision <= 6,
"Paimon Iceberg compatibility only support timestamp type with
precision from 3 to 6.");
long encoded =
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong();
- return precision == 3 ? Timestamp.fromEpochMillis(encoded) :
Timestamp.fromMicros(encoded);
+ return Timestamp.fromMicros(encoded);
}
private static ByteBuffer timeToByteBuffer(int millisOfDay, int precision)
{
diff --git
a/paimon-core/src/test/java/org/apache/paimon/iceberg/manifest/IcebergConversionsTimestampTest.java
b/paimon-core/src/test/java/org/apache/paimon/iceberg/manifest/IcebergConversionsTimestampTest.java
index 73da8331c1..8a6fe8278e 100644
---
a/paimon-core/src/test/java/org/apache/paimon/iceberg/manifest/IcebergConversionsTimestampTest.java
+++
b/paimon-core/src/test/java/org/apache/paimon/iceberg/manifest/IcebergConversionsTimestampTest.java
@@ -101,9 +101,8 @@ class IcebergConversionsTimestampTest {
private static Stream<Arguments> provideTimestampToPaimonCases() {
return Stream.of(
- // Provide binary in micros; p=3..6 should all parse as micros
- Arguments.of(3, -1356022717123L, "1927-01-12T07:01:22.877"),
- Arguments.of(3, 1713790983524L, "2024-04-22T13:03:03.524"),
+ Arguments.of(3, -1356022717123000L, "1927-01-12T07:01:22.877"),
+ Arguments.of(3, 1713790983524000L, "2024-04-22T13:03:03.524"),
Arguments.of(6, 1640690931207203L,
"2021-12-28T11:28:51.207203"));
}