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 fa9d60da fix(transforms): fix truncate transform for negative ints
(#608)
fa9d60da is described below
commit fa9d60da93be0e54eea4460b87aa6f519991bbea
Author: Matt Topol <[email protected]>
AuthorDate: Wed Oct 22 13:24:53 2025 -0400
fix(transforms): fix truncate transform for negative ints (#608)
fixes #603
Also adds unit tests for truncate transforms of various types
---
transforms.go | 6 ++++--
transforms_test.go | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/transforms.go b/transforms.go
index bd4aee4c..720e8429 100644
--- a/transforms.go
+++ b/transforms.go
@@ -413,8 +413,9 @@ func (t TruncateTransform) Transformer(src Type) (func(any)
any, error) {
}
val := v.(int32)
+ width := int32(t.Width)
- return val - (val % int32(t.Width))
+ return val - (((val % width) + width) % width)
}, nil
case Int64Type:
return func(v any) any {
@@ -423,8 +424,9 @@ func (t TruncateTransform) Transformer(src Type) (func(any)
any, error) {
}
val := v.(int64)
+ width := int64(t.Width)
- return val - (val % int64(t.Width))
+ return val - (((val % width) + width) % width)
}, nil
case StringType, BinaryType:
return func(v any) any {
diff --git a/transforms_test.go b/transforms_test.go
index 92e20513..ce6fa7af 100644
--- a/transforms_test.go
+++ b/transforms_test.go
@@ -19,12 +19,14 @@ package iceberg_test
import (
"bytes"
+ "fmt"
"reflect"
"strings"
"testing"
"time"
"github.com/apache/arrow-go/v18/arrow/decimal"
+ "github.com/apache/arrow-go/v18/arrow/decimal128"
"github.com/apache/iceberg-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -355,3 +357,37 @@ func TestCanTransform(t *testing.T) {
}
}
}
+
+func TestTruncateTransform(t *testing.T) {
+ tests := []struct {
+ width int
+ value iceberg.Literal
+ expected iceberg.Literal
+ }{
+ {10, iceberg.Int32Literal(1), iceberg.Int32Literal(0)},
+ {10, iceberg.Int32Literal(-1), iceberg.Int32Literal(-10)},
+ {10, iceberg.Int64Literal(1), iceberg.Int64Literal(0)},
+ {10, iceberg.Int64Literal(-1), iceberg.Int64Literal(-10)},
+ {50, iceberg.DecimalLiteral{
+ Val: decimal128.FromI64(1065),
+ Scale: 2,
+ }, iceberg.DecimalLiteral{
+ Val: decimal128.FromI64(1050),
+ Scale: 2,
+ }},
+ {3, iceberg.StringLiteral("abcdef"),
iceberg.StringLiteral("abc")},
+ {
+ 3, iceberg.BinaryLiteral([]byte{0x01, 0x02, 0x03, 0x04,
0x05}),
+ iceberg.BinaryLiteral([]byte{0x01, 0x02, 0x03}),
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(fmt.Sprintf("width=%d value=%v", tt.width,
tt.value.Any()), func(t *testing.T) {
+ transform := iceberg.TruncateTransform{Width: tt.width}
+ result :=
transform.Apply(iceberg.Optional[iceberg.Literal]{Val: tt.value, Valid: true})
+ require.True(t, result.Valid)
+ assert.Equal(t, tt.expected, result.Val)
+ })
+ }
+}