You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by ze...@apache.org on 2026/06/08 19:06:22 UTC
(iceberg-go) branch main updated: fix(table): reject time64[ns] in partition literal extraction (#1115) (#1159)
This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-go.git
The following commit(s) were added to refs/heads/main by this push:
new 8d85415a fix(table): reject time64[ns] in partition literal extraction (#1115) (#1159)
8d85415a is described below
commit 8d85415a5f2ec0b7ee992cb663dfe56724b47b62
Author: Tanmay Rauth <t_...@apple.com>
AuthorDate: Tue Jun 9 00:36:16 2026 +0530
fix(table): reject time64[ns] in partition literal extraction (#1115) (#1159)
`getArrowValueAsIcebergLiteral` previously assumed every `*array.Time64`
already held microseconds and ignored the Arrow `Time64Type.Unit`. This
is unreachable today because the schema-conversion path in
`arrow_utils.go` only accepts `time64[us]`, but the helper was still
silently producing wrong partition keys if `time64[ns]` ever reached it.
Inspect `Time64Type.Unit` and return `iceberg.ErrInvalidSchema` for any
unit other than microseconds, mirroring the schema-conversion error. Add
a focused unit test covering both the success and rejection paths.
Closes https://github.com/apache/iceberg-go/issues/1115
---
table/partitioned_fanout_writer.go | 4 ++++
table/partitioned_fanout_writer_test.go | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/table/partitioned_fanout_writer.go b/table/partitioned_fanout_writer.go
index 0d0c5378..87ad78b4 100644
--- a/table/partitioned_fanout_writer.go
+++ b/table/partitioned_fanout_writer.go
@@ -390,6 +390,10 @@ func getArrowValueAsIcebergLiteral(column arrow.Array, row int, sourceType icebe
return iceberg.NewLiteral(iceberg.Date(arr.Value(row))), nil
case *array.Time64:
+ dt, ok := arr.DataType().(*arrow.Time64Type)
+ if !ok || dt.Unit != arrow.Microsecond {
+ return nil, fmt.Errorf("%w: unsupported arrow type for conversion - %s", iceberg.ErrInvalidSchema, arr.DataType())
+ }
return iceberg.NewLiteral(iceberg.Time(arr.Value(row))), nil
case *array.Timestamp:
diff --git a/table/partitioned_fanout_writer_test.go b/table/partitioned_fanout_writer_test.go
index ae29b76a..677f2152 100644
--- a/table/partitioned_fanout_writer_test.go
+++ b/table/partitioned_fanout_writer_test.go
@@ -585,3 +585,27 @@ func (s *FanoutWriterTestSuite) createComprehensiveTestRecord() arrow.RecordBatc
return bldr.NewRecordBatch()
}
+
+func (s *FanoutWriterTestSuite) TestGetArrowValueAsIcebergLiteralTime64() {
+ // time64[us]: value passes through unchanged.
+ usBldr := array.NewTime64Builder(s.mem, &arrow.Time64Type{Unit: arrow.Microsecond})
+ defer usBldr.Release()
+ usBldr.Append(arrow.Time64(5_000_000))
+ usArr := usBldr.NewTime64Array()
+ defer usArr.Release()
+
+ lit, err := getArrowValueAsIcebergLiteral(usArr, 0, iceberg.PrimitiveTypes.Time)
+ s.Require().NoError(err)
+ s.Equal(iceberg.NewLiteral(iceberg.Time(5_000_000)), lit)
+
+ // time64[ns]: explicitly rejected to avoid silently producing wrong partition keys.
+ nsBldr := array.NewTime64Builder(s.mem, &arrow.Time64Type{Unit: arrow.Nanosecond})
+ defer nsBldr.Release()
+ nsBldr.Append(arrow.Time64(5_000_000_000))
+ nsArr := nsBldr.NewTime64Array()
+ defer nsArr.Release()
+
+ _, err = getArrowValueAsIcebergLiteral(nsArr, 0, iceberg.PrimitiveTypes.Time)
+ s.Require().ErrorIs(err, iceberg.ErrInvalidSchema)
+ s.Contains(err.Error(), "time64[ns]")
+}