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 eee4a82b4 refactor(types)!: return errors from fixed and decimal
constructors (#2331)
eee4a82b4 is described below
commit eee4a82b43da0989f1101c8f0132119974406543
Author: Minh Vu <[email protected]>
AuthorDate: Mon Oct 26 21:04:42 2026 +0100
refactor(types)!: return errors from fixed and decimal constructors (#2331)
Signed-off-by: Minh Vu <[email protected]>
Co-authored-by: Matt Topol <[email protected]>
---
bound_set_literal_view_test.go | 4 +-
catalog/glue/schema_test.go | 8 +-
catalog/hive/hive_test.go | 4 +-
catalog/rest/scan_planning_parity_test.go | 4 +-
catalog/rest/scan_task_decoder_test.go | 16 +-
data_file_codec_bench_test.go | 2 +-
data_file_codec_fingerprint_test.go | 24 +--
data_file_codec_test.go | 6 +-
expr_json_test.go | 4 +-
exprs_test.go | 14 +-
literals_test.go | 174 ++++++++++-----------
manifest_partition_bench_test.go | 6 +-
manifest_test.go | 10 +-
partitions_test.go | 4 +-
schema_compatibility_test.go | 18 +--
table/arrow_filter_plan_key_test.go | 10 +-
table/arrow_filter_plan_test.go | 10 +-
table/arrow_scanner_bench_test.go | 4 +-
table/arrow_utils.go | 4 +-
table/arrow_utils_test.go | 14 +-
table/equality_delete_index_metrics_test.go | 12 +-
table/equality_delete_writer_test.go | 4 +-
table/evaluators_invalid_bounds_test.go | 2 +-
table/evaluators_row_group_test.go | 4 +-
table/in_predicate_extrema_bench_test.go | 8 +-
table/in_predicate_extrema_test.go | 12 +-
table/inspect_internal_test.go | 6 +-
table/inspect_partition_append_test.go | 6 +-
table/internal/parquet_files_test.go | 24 +--
table/internal/utils_test.go | 2 +-
table/internal/variant_bounds.go | 7 +-
table/internal/variant_bounds_test.go | 26 +++
table/metadata_internal_test.go | 2 +-
table/partition_residual_test.go | 2 +-
table/partitioned_fanout_writer_review_test.go | 4 +-
table/partitioned_fanout_writer_test.go | 14 +-
table/scanner_internal_test.go | 2 +-
table/substrait/substrait_decimal_internal_test.go | 4 +-
table/substrait/substrait_test.go | 4 +-
table/table_test.go | 8 +-
table/transaction_test.go | 8 +-
table/update_schema_test.go | 16 +-
table/variant_residual_fastpath_test.go | 4 +-
table/variant_residual_test.go | 4 +-
table/variant_shredded_write_test.go | 8 +-
transforms_decimal_bench_test.go | 4 +-
transforms_test.go | 28 ++--
types.go | 36 ++++-
types_test.go | 93 +++++++----
variant_cast_test.go | 10 +-
variant_extract_test.go | 2 +-
visitors_test.go | 10 +-
website/src/releases.md | 1 +
53 files changed, 402 insertions(+), 315 deletions(-)
diff --git a/bound_set_literal_view_test.go b/bound_set_literal_view_test.go
index 2ee7fe00c..7c9bfb874 100644
--- a/bound_set_literal_view_test.go
+++ b/bound_set_literal_view_test.go
@@ -44,8 +44,8 @@ func TestBoundSetPredicateLiteralsCloneMutableMembers(t
*testing.T) {
}{
{name: "binary_in", typ: iceberg.PrimitiveTypes.Binary, op:
iceberg.OpIn},
{name: "binary_not_in", typ: iceberg.PrimitiveTypes.Binary, op:
iceberg.OpNotIn},
- {name: "fixed_in", typ: iceberg.FixedTypeOf(16), op:
iceberg.OpIn},
- {name: "fixed_not_in", typ: iceberg.FixedTypeOf(16), op:
iceberg.OpNotIn},
+ {name: "fixed_in", typ: iceberg.MustFixedTypeOf(16), op:
iceberg.OpIn},
+ {name: "fixed_not_in", typ: iceberg.MustFixedTypeOf(16), op:
iceberg.OpNotIn},
{name: "geometry_in", typ: geometry, op: iceberg.OpIn},
{name: "geometry_not_in", typ: geometry, op: iceberg.OpNotIn},
{name: "geography_in", typ: geography, op: iceberg.OpIn},
diff --git a/catalog/glue/schema_test.go b/catalog/glue/schema_test.go
index cdc9cf1bf..71e0a1991 100644
--- a/catalog/glue/schema_test.go
+++ b/catalog/glue/schema_test.go
@@ -96,19 +96,19 @@ func TestIcebergTypeToGlueType(t *testing.T) {
},
{
name: "decimal type",
- input: iceberg.DecimalTypeOf(10, 2),
+ input: iceberg.MustDecimalTypeOf(10, 2),
expected: "decimal(10,2)",
},
{
name: "fixed type",
- input: iceberg.FixedTypeOf(16),
+ input: iceberg.MustFixedTypeOf(16),
expected: "binary",
},
{
name: "nested fixed type",
input: &iceberg.ListType{
ElementID: 1,
- Element: iceberg.FixedTypeOf(16),
+ Element: iceberg.MustFixedTypeOf(16),
ElementRequired: true,
},
expected: "array<binary>",
@@ -153,7 +153,7 @@ func TestFieldToGlueColumn(t *testing.T) {
field: iceberg.NestedField{
ID: 2,
Name: "price",
- Type: iceberg.DecimalTypeOf(10, 2),
+ Type: iceberg.MustDecimalTypeOf(10, 2),
Required: false,
Doc: "Price with 2 decimal places",
},
diff --git a/catalog/hive/hive_test.go b/catalog/hive/hive_test.go
index 221413fc5..9190b7571 100644
--- a/catalog/hive/hive_test.go
+++ b/catalog/hive/hive_test.go
@@ -1780,8 +1780,8 @@ func TestIcebergTypeToHiveType(t *testing.T) {
{"string", iceberg.PrimitiveTypes.String, "string"},
{"uuid", iceberg.PrimitiveTypes.UUID, "string"},
{"binary", iceberg.PrimitiveTypes.Binary, "binary"},
- {"decimal", iceberg.DecimalTypeOf(10, 2), "decimal(10,2)"},
- {"fixed", iceberg.FixedTypeOf(16), "binary(16)"},
+ {"decimal", iceberg.MustDecimalTypeOf(10, 2), "decimal(10,2)"},
+ {"fixed", iceberg.MustFixedTypeOf(16), "binary(16)"},
}
for _, tt := range tests {
diff --git a/catalog/rest/scan_planning_parity_test.go
b/catalog/rest/scan_planning_parity_test.go
index 13281c388..5434bb922 100644
--- a/catalog/rest/scan_planning_parity_test.go
+++ b/catalog/rest/scan_planning_parity_test.go
@@ -163,14 +163,14 @@ func newPlanningParityTable(t *testing.T)
(table.Metadata, *iceio.MemFS) {
schema := iceberg.NewSchema(0,
iceberg.NestedField{ID: 1, Name: "tenant", Type:
iceberg.PrimitiveTypes.Int32},
iceberg.NestedField{ID: 2, Name: "value", Type:
iceberg.PrimitiveTypes.Int32},
- iceberg.NestedField{ID: 3, Name: "amount", Type:
iceberg.DecimalTypeOf(12, 2)},
+ iceberg.NestedField{ID: 3, Name: "amount", Type:
iceberg.MustDecimalTypeOf(12, 2)},
iceberg.NestedField{ID: 4, Name: "ts", Type:
iceberg.PrimitiveTypes.Timestamp},
iceberg.NestedField{ID: 5, Name: "tstz", Type:
iceberg.PrimitiveTypes.TimestampTz},
iceberg.NestedField{ID: 6, Name: "day", Type:
iceberg.PrimitiveTypes.Date},
iceberg.NestedField{ID: 7, Name: "clock", Type:
iceberg.PrimitiveTypes.Time},
iceberg.NestedField{ID: 8, Name: "uuid", Type:
iceberg.PrimitiveTypes.UUID},
iceberg.NestedField{ID: 9, Name: "blob", Type:
iceberg.PrimitiveTypes.Binary},
- iceberg.NestedField{ID: 10, Name: "fixed", Type:
iceberg.FixedTypeOf(3)},
+ iceberg.NestedField{ID: 10, Name: "fixed", Type:
iceberg.MustFixedTypeOf(3)},
iceberg.NestedField{ID: 11, Name: "nested", Type:
&iceberg.StructType{FieldList: []iceberg.NestedField{
{ID: 16, Name: "text", Type:
iceberg.PrimitiveTypes.String},
}}},
diff --git a/catalog/rest/scan_task_decoder_test.go
b/catalog/rest/scan_task_decoder_test.go
index 1ad68e576..d87b2066f 100644
--- a/catalog/rest/scan_task_decoder_test.go
+++ b/catalog/rest/scan_task_decoder_test.go
@@ -366,7 +366,7 @@ func TestRESTValueMapUsesIcebergBinaryEncoding(t
*testing.T) {
decoded, err := decodeValueMap("lower-bounds", &bounds)
require.NoError(t, err)
- decimalType := iceberg.DecimalTypeOf(9, 2)
+ decimalType := iceberg.MustDecimalTypeOf(9, 2)
tests := []struct {
name string
fieldID int
@@ -605,8 +605,8 @@ func TestDecodeScanTasksRejectsDeleteFilesWithoutTasks(t
*testing.T) {
func TestDecodePartitionLiteralCoversPrimitiveWireTypes(t *testing.T) {
t.Parallel()
- decimalType := iceberg.DecimalTypeOf(9, 2)
- fixedType := iceberg.FixedTypeOf(4)
+ decimalType := iceberg.MustDecimalTypeOf(9, 2)
+ fixedType := iceberg.MustFixedTypeOf(4)
tests := []struct {
name string
raw string
@@ -662,7 +662,7 @@ func TestDecodePartitionLiteralRejectsInvalidValues(t
*testing.T) {
{"null", `null`, iceberg.PrimitiveTypes.Int64, "null is not
valid"},
{"int32 overflow", `2147483648`, iceberg.PrimitiveTypes.Int32,
"outside int32 range"},
{"long fraction", `1.5`, iceberg.PrimitiveTypes.Int64, "invalid
integer value"},
- {"wrong fixed width", `"00FF"`, iceberg.FixedTypeOf(4),
"different length"},
+ {"wrong fixed width", `"00FF"`, iceberg.MustFixedTypeOf(4),
"different length"},
{"invalid binary hex", `"XYZ"`, iceberg.PrimitiveTypes.Binary,
"hexadecimal"},
{"nested value", `{"x":1}`, iceberg.PrimitiveTypes.String,
"invalid string value"},
} {
@@ -806,8 +806,8 @@ func newScanTaskDecoderMetadata() *scanTaskDecoderMetadata {
iceberg.NestedField{ID: 1, Name: "id", Type:
iceberg.PrimitiveTypes.Int64, Required: true},
iceberg.NestedField{ID: 2, Name: "category", Type:
iceberg.PrimitiveTypes.String},
iceberg.NestedField{ID: 3, Name: "event_date", Type:
iceberg.PrimitiveTypes.Date},
- iceberg.NestedField{ID: 4, Name: "amount", Type:
iceberg.DecimalTypeOf(9, 2)},
- iceberg.NestedField{ID: 5, Name: "code", Type:
iceberg.FixedTypeOf(4)},
+ iceberg.NestedField{ID: 4, Name: "amount", Type:
iceberg.MustDecimalTypeOf(9, 2)},
+ iceberg.NestedField{ID: 5, Name: "code", Type:
iceberg.MustFixedTypeOf(4)},
iceberg.NestedField{ID: 6, Name: "event_time", Type:
iceberg.PrimitiveTypes.TimestampTzNs},
iceberg.NestedField{ID: 7, Name: "score", Type:
iceberg.PrimitiveTypes.Float64},
iceberg.NestedField{ID: 8, Name: "lower_int", Type:
iceberg.PrimitiveTypes.Int32},
@@ -951,7 +951,7 @@ func
TestDecodeScanTasksAcceptsPointerAndUnknownPartitionTransforms(t *testing.T
func TestDecodePartitionLogicalMetadata(t *testing.T) {
t.Parallel()
- decimalType := iceberg.DecimalTypeOf(9, 2)
+ decimalType := iceberg.MustDecimalTypeOf(9, 2)
for _, tt := range []struct {
name string
typ iceberg.Type
@@ -961,7 +961,7 @@ func TestDecodePartitionLogicalMetadata(t *testing.T) {
}{
{name: "unpartitioned"},
{name: "integer", typ: iceberg.PrimitiveTypes.Int64, raw: `34`,
want: int64(34)},
- {name: "fixed", typ: iceberg.FixedTypeOf(4), raw: `"78797A21"`,
want: []byte("xyz!")},
+ {name: "fixed", typ: iceberg.MustFixedTypeOf(4), raw:
`"78797A21"`, want: []byte("xyz!")},
{name: "null date", typ: iceberg.PrimitiveTypes.Date, raw:
`null`},
{name: "null decimal", typ: decimalType, raw: `null`},
{name: "date", typ: iceberg.PrimitiveTypes.Date, raw:
`"2026-07-17"`, want: mustLiteral(t, "2026-07-17",
iceberg.PrimitiveTypes.Date).Any(), logicalType: atype.Date},
diff --git a/data_file_codec_bench_test.go b/data_file_codec_bench_test.go
index f7080065a..c118bc563 100644
--- a/data_file_codec_bench_test.go
+++ b/data_file_codec_bench_test.go
@@ -30,7 +30,7 @@ func BenchmarkDataFileSchemaCache(b *testing.B) {
NestedField{ID: 1, Name: "id", Type: Int64Type{}},
NestedField{ID: 2, Name: "category", Type: StringType{}},
NestedField{ID: 3, Name: "ts", Type: TimestampType{}},
- NestedField{ID: 4, Name: "price", Type: DecimalTypeOf(10, 2)},
+ NestedField{ID: 4, Name: "price", Type: MustDecimalTypeOf(10,
2)},
NestedField{ID: 5, Name: "nested", Type: &StructType{FieldList:
[]NestedField{
{ID: 6, Name: "value", Type: StringType{}},
}}},
diff --git a/data_file_codec_fingerprint_test.go
b/data_file_codec_fingerprint_test.go
index 204b4a956..40603fe8a 100644
--- a/data_file_codec_fingerprint_test.go
+++ b/data_file_codec_fingerprint_test.go
@@ -48,11 +48,11 @@ func TestPartitionTypeFingerprintMatchesAvroConversion(t
*testing.T) {
VariantType{},
GeometryType{},
GeographyType{},
- FixedTypeOf(8),
- FixedTypeOf(16),
- DecimalTypeOf(10, 2),
- DecimalTypeOf(11, 2),
- DecimalTypeOf(10, 3),
+ MustFixedTypeOf(8),
+ MustFixedTypeOf(16),
+ MustDecimalTypeOf(10, 2),
+ MustDecimalTypeOf(11, 2),
+ MustDecimalTypeOf(10, 3),
&StructType{FieldList: []NestedField{{ID: 2, Name: "child",
Type: StringType{}}}},
&ListType{ElementID: 2, Element: StringType{}},
&MapType{KeyID: 2, KeyType: StringType{}, ValueID: 3,
ValueType: Int64Type{}},
@@ -90,11 +90,11 @@ func
TestManifestEntrySchemaForMultipleParameterizedFields(t *testing.T) {
decimal Type
fixed Type
}{
- {"ordered", NewPartitionSpec(price, code),
DecimalTypeOf(10, 2), FixedTypeOf(16)},
- {"reversed", NewPartitionSpec(code, price),
DecimalTypeOf(10, 2), FixedTypeOf(16)},
- {"precision", NewPartitionSpec(price, code),
DecimalTypeOf(11, 2), FixedTypeOf(16)},
- {"scale", NewPartitionSpec(price, code),
DecimalTypeOf(10, 3), FixedTypeOf(16)},
- {"fixed_size", NewPartitionSpec(price, code),
DecimalTypeOf(10, 2), FixedTypeOf(8)},
+ {"ordered", NewPartitionSpec(price, code),
MustDecimalTypeOf(10, 2), MustFixedTypeOf(16)},
+ {"reversed", NewPartitionSpec(code, price),
MustDecimalTypeOf(10, 2), MustFixedTypeOf(16)},
+ {"precision", NewPartitionSpec(price, code),
MustDecimalTypeOf(11, 2), MustFixedTypeOf(16)},
+ {"scale", NewPartitionSpec(price, code),
MustDecimalTypeOf(10, 3), MustFixedTypeOf(16)},
+ {"fixed_size", NewPartitionSpec(price, code),
MustDecimalTypeOf(10, 2), MustFixedTypeOf(8)},
} {
t.Run(tc.name+"/v"+strconv.Itoa(version), func(t
*testing.T) {
t.Parallel()
@@ -120,8 +120,8 @@ func
TestManifestEntrySchemaForMultipleParameterizedFields(t *testing.T) {
func TestPartitionSchemaFingerprintNameBoundaries(t *testing.T) {
schema := NewSchema(1,
- NestedField{ID: 1, Name: "source_price", Type:
DecimalTypeOf(10, 2)},
- NestedField{ID: 2, Name: "source_code", Type: FixedTypeOf(16)},
+ NestedField{ID: 1, Name: "source_price", Type:
MustDecimalTypeOf(10, 2)},
+ NestedField{ID: 2, Name: "source_code", Type:
MustFixedTypeOf(16)},
)
// Exercise the key's length prefixes independently of Avro name
validation.
names := []string{"a", "ab", "1:a", "a:q10:2:", "f16:", "λ"}
diff --git a/data_file_codec_test.go b/data_file_codec_test.go
index 74501ec10..013bd58fb 100644
--- a/data_file_codec_test.go
+++ b/data_file_codec_test.go
@@ -299,7 +299,7 @@ func TestCloneDataFileAvroFieldsCopiesOnlyAvroFields(t
*testing.T) {
func TestMarshalAvroEntryDecimalPartitionRoundTrip(t *testing.T) {
schema := NewSchema(0,
- NestedField{ID: 1, Name: "price", Type: DecimalTypeOf(10, 2)},
+ NestedField{ID: 1, Name: "price", Type: MustDecimalTypeOf(10,
2)},
)
spec := NewPartitionSpecID(1,
PartitionField{SourceIDs: []int{1}, FieldID: 1000, Name:
"price", Transform: IdentityTransform{}},
@@ -501,8 +501,8 @@ func TestManifestEntrySchemaForMatchesPartitionAvroShape(t
*testing.T) {
UUIDType{},
BooleanType{},
BinaryType{},
- FixedTypeOf(8), FixedTypeOf(16),
- DecimalTypeOf(10, 2), DecimalTypeOf(11, 2), DecimalTypeOf(10,
3),
+ MustFixedTypeOf(8), MustFixedTypeOf(16),
+ MustDecimalTypeOf(10, 2), MustDecimalTypeOf(11, 2),
MustDecimalTypeOf(10, 3),
UnknownType{},
}
for _, version := range []int{1, 2, 3} {
diff --git a/expr_json_test.go b/expr_json_test.go
index cdf0b2b2d..7dfc011c7 100644
--- a/expr_json_test.go
+++ b/expr_json_test.go
@@ -155,7 +155,7 @@ func TestMarshalExpressionTypedLiterals(t *testing.T) {
{"date", mustLit(t, "2022-08-14", iceberg.PrimitiveTypes.Date),
`{"type":"eq","term":"d","value":"2022-08-14"}`},
{"uuid",
iceberg.UUIDLiteral(uuid.MustParse("f79c3e09-677c-4bbd-a479-3f349cb785e7")),
`{"type":"eq","term":"d","value":"f79c3e09-677c-4bbd-a479-3f349cb785e7"}`},
{"binary", iceberg.BinaryLiteral([]byte{0x01, 0x02, 0x03}),
`{"type":"eq","term":"d","value":"010203"}`},
- {"decimal", mustLit(t, "3.14", iceberg.DecimalTypeOf(9, 2)),
`{"type":"eq","term":"d","value":"3.14"}`},
+ {"decimal", mustLit(t, "3.14", iceberg.MustDecimalTypeOf(9,
2)), `{"type":"eq","term":"d","value":"3.14"}`},
}
for _, tt := range tests {
@@ -675,7 +675,7 @@ func TestUnmarshalExpressionLiteralWrapperErrors(t
*testing.T) {
// doesn't match the column's declared length.
func TestUnmarshalExpressionFixedLength(t *testing.T) {
schema := iceberg.NewSchema(0,
- iceberg.NestedField{ID: 1, Name: "f", Type:
iceberg.FixedTypeOf(4)},
+ iceberg.NestedField{ID: 1, Name: "f", Type:
iceberg.MustFixedTypeOf(4)},
)
_, err :=
iceberg.ParseExpr([]byte(`{"type":"eq","term":"f","value":"0102"}`), schema)
require.ErrorIs(t, err, iceberg.ErrInvalidArgument)
diff --git a/exprs_test.go b/exprs_test.go
index 2ccd54a81..5286b0f8a 100644
--- a/exprs_test.go
+++ b/exprs_test.go
@@ -251,11 +251,11 @@ func TestRefTypes(t *testing.T) {
iceberg.NestedField{ID: 6, Name: "f", Type:
iceberg.PrimitiveTypes.Date},
iceberg.NestedField{ID: 7, Name: "g", Type:
iceberg.PrimitiveTypes.Time},
iceberg.NestedField{ID: 8, Name: "h", Type:
iceberg.PrimitiveTypes.Timestamp},
- iceberg.NestedField{ID: 9, Name: "i", Type:
iceberg.DecimalTypeOf(9, 2)},
+ iceberg.NestedField{ID: 9, Name: "i", Type:
iceberg.MustDecimalTypeOf(9, 2)},
iceberg.NestedField{ID: 10, Name: "j", Type:
iceberg.PrimitiveTypes.String},
iceberg.NestedField{ID: 11, Name: "k", Type:
iceberg.PrimitiveTypes.Binary},
iceberg.NestedField{ID: 12, Name: "l", Type:
iceberg.PrimitiveTypes.UUID},
- iceberg.NestedField{ID: 13, Name: "m", Type:
iceberg.FixedTypeOf(5)},
+ iceberg.NestedField{ID: 13, Name: "m", Type:
iceberg.MustFixedTypeOf(5)},
iceberg.NestedField{ID: 14, Name: "n", Type:
iceberg.VariantType{}},
iceberg.NestedField{ID: 15, Name: "o", Type:
iceberg.PrimitiveTypes.TimestampNs},
iceberg.NestedField{ID: 16, Name: "p", Type:
iceberg.PrimitiveTypes.TimestampTzNs})
@@ -334,7 +334,7 @@ func TestRefTypes(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, iceberg.OpEQ, fx.Op())
- assert.True(t,
fx.(iceberg.BoundLiteralPredicate).Literal().Type().Equals(iceberg.FixedTypeOf(5)))
+ assert.True(t,
fx.(iceberg.BoundLiteralPredicate).Literal().Type().Equals(iceberg.MustFixedTypeOf(5)))
})
t.Run("uuid", func(t *testing.T) {
@@ -412,9 +412,9 @@ func TestRefTypes(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, iceberg.OpIn, fx.Op())
- assert.True(t,
fx.(iceberg.BoundSetPredicate).Ref().Type().Equals(iceberg.FixedTypeOf(5)))
+ assert.True(t,
fx.(iceberg.BoundSetPredicate).Ref().Type().Equals(iceberg.MustFixedTypeOf(5)))
for _, v := range
fx.(iceberg.BoundSetPredicate).Literals().Members() {
- assert.True(t,
v.Type().Equals(iceberg.FixedTypeOf(5)))
+ assert.True(t,
v.Type().Equals(iceberg.MustFixedTypeOf(5)))
}
})
@@ -544,7 +544,7 @@ func TestInNotInSimplifications(t *testing.T) {
},
{
name: "fixed",
- typ: iceberg.FixedTypeOf(16),
+ typ: iceberg.MustFixedTypeOf(16),
lits: func(first, second []byte)
[]iceberg.Literal {
return
[]iceberg.Literal{iceberg.NewLiteral(first), iceberg.NewLiteral(second)}
},
@@ -848,7 +848,7 @@ func TestToString(t *testing.T) {
iceberg.NestedField{ID: 5, Name: "e", Type:
iceberg.PrimitiveTypes.Int32},
iceberg.NestedField{ID: 6, Name: "f", Type:
iceberg.PrimitiveTypes.Int32},
iceberg.NestedField{ID: 7, Name: "g", Type:
iceberg.PrimitiveTypes.Float32},
- iceberg.NestedField{ID: 8, Name: "h", Type:
iceberg.DecimalTypeOf(8, 4)},
+ iceberg.NestedField{ID: 8, Name: "h", Type:
iceberg.MustDecimalTypeOf(8, 4)},
iceberg.NestedField{ID: 9, Name: "i", Type:
iceberg.PrimitiveTypes.UUID},
iceberg.NestedField{ID: 10, Name: "j", Type:
iceberg.PrimitiveTypes.Bool},
iceberg.NestedField{ID: 11, Name: "k", Type:
iceberg.PrimitiveTypes.Bool},
diff --git a/literals_test.go b/literals_test.go
index c3bcb941a..7b52350fd 100644
--- a/literals_test.go
+++ b/literals_test.go
@@ -81,15 +81,15 @@ func TestIntToDecimalConversion(t *testing.T) {
val iceberg.Decimal
}{
{
- iceberg.DecimalTypeOf(9, 0),
+ iceberg.MustDecimalTypeOf(9, 0),
iceberg.Decimal{Val: decimal128.FromI64(34), Scale: 0},
},
{
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.Decimal{Val: decimal128.FromI64(3400), Scale:
2},
},
{
- iceberg.DecimalTypeOf(9, 4),
+ iceberg.MustDecimalTypeOf(9, 4),
iceberg.Decimal{Val: decimal128.FromI64(340000), Scale:
4},
},
}
@@ -453,23 +453,23 @@ func TestFloat64toFloat32OutsideBounds(t *testing.T) {
func TestDecimalToDecimalConversion(t *testing.T) {
lit := iceberg.NewLiteral(iceberg.Decimal{Val:
decimal128.FromI64(3411), Scale: 2})
- v, err := lit.To(iceberg.DecimalTypeOf(9, 2))
+ v, err := lit.To(iceberg.MustDecimalTypeOf(9, 2))
require.NoError(t, err)
assert.Equal(t, lit, v)
- v, err = lit.To(iceberg.DecimalTypeOf(11, 2))
+ v, err = lit.To(iceberg.MustDecimalTypeOf(11, 2))
require.NoError(t, err)
assert.Equal(t, lit, v)
- _, err = lit.To(iceberg.DecimalTypeOf(9, 0))
+ _, err = lit.To(iceberg.MustDecimalTypeOf(9, 0))
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, "could not convert 34.11 to decimal(9, 0)")
- _, err = lit.To(iceberg.DecimalTypeOf(9, 1))
+ _, err = lit.To(iceberg.MustDecimalTypeOf(9, 1))
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, "could not convert 34.11 to decimal(9, 1)")
- _, err = lit.To(iceberg.DecimalTypeOf(9, 3))
+ _, err = lit.To(iceberg.MustDecimalTypeOf(9, 3))
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, "could not convert 34.11 to decimal(9, 3)")
}
@@ -797,7 +797,7 @@ func TestStringLiteralConversion(t *testing.T) {
}
func TestLiteralIdentityConversions(t *testing.T) {
- fixedLit, _ := iceberg.NewLiteral([]byte{0x01, 0x02,
0x03}).To(iceberg.FixedTypeOf(3))
+ fixedLit, _ := iceberg.NewLiteral([]byte{0x01, 0x02,
0x03}).To(iceberg.MustFixedTypeOf(3))
tests := []struct {
lit iceberg.Literal
@@ -810,7 +810,7 @@ func TestLiteralIdentityConversions(t *testing.T) {
{iceberg.NewLiteral(float64(3.5028235e38)),
iceberg.PrimitiveTypes.Float64},
{
iceberg.NewLiteral(iceberg.Decimal{Val:
decimal128.FromI64(3455), Scale: 2}),
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
},
{iceberg.NewLiteral(iceberg.Date(19079)),
iceberg.PrimitiveTypes.Date},
{
@@ -819,7 +819,7 @@ func TestLiteralIdentityConversions(t *testing.T) {
},
{iceberg.NewLiteral("abc"), iceberg.PrimitiveTypes.String},
{iceberg.NewLiteral(uuid.New()), iceberg.PrimitiveTypes.UUID},
- {fixedLit, iceberg.FixedTypeOf(3)},
+ {fixedLit, iceberg.MustFixedTypeOf(3)},
{iceberg.NewLiteral([]byte{0x01, 0x02, 0x03}),
iceberg.PrimitiveTypes.Binary},
}
@@ -1067,14 +1067,14 @@ func TestFixedLiteral(t *testing.T) {
assert.Equal(t, 0, cmp(fixedLit013, fixedLit013))
testUuid := uuid.New()
- lit, err := iceberg.NewLiteral(testUuid[:]).To(iceberg.FixedTypeOf(16))
+ lit, err :=
iceberg.NewLiteral(testUuid[:]).To(iceberg.MustFixedTypeOf(16))
require.NoError(t, err)
uuidLit, err := lit.To(iceberg.PrimitiveTypes.UUID)
require.NoError(t, err)
assert.EqualValues(t, uuidLit, testUuid)
- fixedUuid, err := uuidLit.To(iceberg.FixedTypeOf(16))
+ fixedUuid, err := uuidLit.To(iceberg.MustFixedTypeOf(16))
require.NoError(t, err)
assert.EqualValues(t, testUuid[:], fixedUuid)
@@ -1107,15 +1107,15 @@ func TestBinaryLiteral(t *testing.T) {
func TestBinaryLiteralConversions(t *testing.T) {
binLit012 := iceberg.NewLiteral([]byte{0x00, 0x01, 0x02})
- fixed, err := binLit012.To(iceberg.FixedTypeOf(3))
+ fixed, err := binLit012.To(iceberg.MustFixedTypeOf(3))
require.NoError(t, err)
assert.Equal(t, iceberg.FixedLiteral{0x00, 0x01, 0x02}, fixed)
- _, err = binLit012.To(iceberg.FixedTypeOf(4))
+ _, err = binLit012.To(iceberg.MustFixedTypeOf(4))
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, "cannot convert BinaryLiteral to fixed[4],
different length - 3 <> 4")
- _, err = binLit012.To(iceberg.FixedTypeOf(2))
+ _, err = binLit012.To(iceberg.MustFixedTypeOf(2))
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, "cannot convert BinaryLiteral to fixed[2],
different length - 3 <> 2")
@@ -1151,11 +1151,11 @@ func TestInvalidBoolLiteralConversions(t *testing.T) {
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
iceberg.PrimitiveTypes.Binary,
- iceberg.FixedTypeOf(2),
+ iceberg.MustFixedTypeOf(2),
})
}
@@ -1210,7 +1210,7 @@ func TestInvalidNumericConversions(t *testing.T) {
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
@@ -1218,7 +1218,7 @@ func TestInvalidNumericConversions(t *testing.T) {
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
@@ -1232,7 +1232,7 @@ func TestInvalidNumericConversions(t *testing.T) {
iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
@@ -1246,7 +1246,7 @@ func TestInvalidNumericConversions(t *testing.T) {
iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
@@ -1259,7 +1259,7 @@ func TestInvalidNumericConversions(t *testing.T) {
iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
}
@@ -1275,10 +1275,10 @@ func TestInvalidDateTimeLiteralConversions(t
*testing.T) {
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
@@ -1292,10 +1292,10 @@ func TestInvalidDateTimeLiteralConversions(t
*testing.T) {
iceberg.PrimitiveTypes.Date,
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
@@ -1307,17 +1307,17 @@ func TestInvalidDateTimeLiteralConversions(t
*testing.T) {
iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64,
iceberg.PrimitiveTypes.Time,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
iceberg.PrimitiveTypes.Binary,
})
}
func TestInvalidStringLiteralConversions(t *testing.T) {
testInvalidLiteralConversions(t, iceberg.NewLiteral("abc"),
[]iceberg.Type{
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
})
}
@@ -1332,12 +1332,12 @@ func TestInvalidBinaryLiteralConversions(t *testing.T) {
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
- iceberg.FixedTypeOf(1),
+ iceberg.MustFixedTypeOf(1),
})
- lit, _ := iceberg.NewLiteral([]byte{0x00, 0x01,
0x02}).To(iceberg.FixedTypeOf(3))
+ lit, _ := iceberg.NewLiteral([]byte{0x00, 0x01,
0x02}).To(iceberg.MustFixedTypeOf(3))
testInvalidLiteralConversions(t, lit, []iceberg.Type{
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.Int32,
@@ -1348,7 +1348,7 @@ func TestInvalidBinaryLiteralConversions(t *testing.T) {
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
})
@@ -1363,7 +1363,7 @@ func TestInvalidBinaryLiteralConversions(t *testing.T) {
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
})
@@ -1382,11 +1382,11 @@ func TestInvalidVariantLiteralConversions(t *testing.T)
{
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
iceberg.PrimitiveTypes.Binary,
- iceberg.FixedTypeOf(2),
+ iceberg.MustFixedTypeOf(2),
})
}
@@ -1401,7 +1401,7 @@ func TestInvalidVariantLiteralConversions(t *testing.T) {
assert.ErrorContains(t, err, "VariantLiteral: could not cast value:
Int32Literal to string")
// a cast error from the underlying literal that lacks ErrBadCast still
gets it
- _, err = variantLiteralOf(t, float32(1e30)).To(iceberg.DecimalTypeOf(9,
2))
+ _, err = variantLiteralOf(t,
float32(1e30)).To(iceberg.MustDecimalTypeOf(9, 2))
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, "VariantLiteral: ")
}
@@ -1417,7 +1417,7 @@ func TestBadStringLiteralCasts(t *testing.T) {
iceberg.PrimitiveTypes.Timestamp,
iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.Bool,
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
iceberg.PrimitiveTypes.UUID,
}
@@ -1500,25 +1500,25 @@ func TestUnmarshalBinary(t *testing.T) {
[]byte{0xf7, 0x9c, 0x3e, 0x09, 0x67, 0x7c, 0x4b, 0xbd,
0xa4, 0x79, 0x3f, 0x34, 0x9c, 0xb7, 0x85, 0xe7},
iceberg.UUIDLiteral(uuid.UUID{0xf7, 0x9c, 0x3e, 0x09,
0x67, 0x7c, 0x4b, 0xbd, 0xa4, 0x79, 0x3f, 0x34, 0x9c, 0xb7, 0x85, 0xe7}),
},
- {iceberg.FixedTypeOf(3), []byte("foo"),
iceberg.FixedLiteral([]byte("foo"))},
+ {iceberg.MustFixedTypeOf(3), []byte("foo"),
iceberg.FixedLiteral([]byte("foo"))},
{iceberg.PrimitiveTypes.Binary, []byte("foo"),
iceberg.BinaryLiteral([]byte("foo"))},
{
- iceberg.DecimalTypeOf(5, 2),
+ iceberg.MustDecimalTypeOf(5, 2),
[]byte{0x30, 0x39},
iceberg.DecimalLiteral{Scale: 2, Val:
decimal128.FromU64(12345)},
},
{
- iceberg.DecimalTypeOf(7, 4),
+ iceberg.MustDecimalTypeOf(7, 4),
[]byte{0x12, 0xd6, 0x87},
iceberg.DecimalLiteral{Scale: 4, Val:
decimal128.FromU64(1234567)},
},
{
- iceberg.DecimalTypeOf(7, 4),
+ iceberg.MustDecimalTypeOf(7, 4),
[]byte{0xff, 0xed, 0x29, 0x79},
iceberg.DecimalLiteral{Scale: 4, Val:
decimal128.FromI64(-1234567)},
},
{
- iceberg.DecimalTypeOf(8, 2),
+ iceberg.MustDecimalTypeOf(8, 2),
[]byte{0x00, 0xbc, 0x61, 0x4e},
iceberg.DecimalLiteral{Scale: 2, Val:
decimal128.FromI64(12345678)},
},
@@ -1554,7 +1554,7 @@ func TestLiteralFromBytesFixedWidth(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- literal, err :=
iceberg.LiteralFromBytes(iceberg.FixedTypeOf(4), test.data)
+ literal, err :=
iceberg.LiteralFromBytes(iceberg.MustFixedTypeOf(4), test.data)
if test.errContains != "" {
require.ErrorIs(t, err,
iceberg.ErrInvalidBinSerialization)
if test.oversized {
@@ -1631,10 +1631,10 @@ func TestRoundTripLiteralBinary(t *testing.T) {
[]byte{0xf7, 0x9c, 0x3e, 0x09, 0x67, 0x7c, 0x4b, 0xbd,
0xa4, 0x79, 0x3f, 0x34, 0x9c, 0xb7, 0x85, 0xe7},
iceberg.UUIDLiteral(uuid.UUID{0xf7, 0x9c, 0x3e, 0x09,
0x67, 0x7c, 0x4b, 0xbd, 0xa4, 0x79, 0x3f, 0x34, 0x9c, 0xb7, 0x85, 0xe7}),
},
- {iceberg.FixedTypeOf(3), []byte("foo"),
iceberg.FixedLiteral([]byte("foo"))},
+ {iceberg.MustFixedTypeOf(3), []byte("foo"),
iceberg.FixedLiteral([]byte("foo"))},
{iceberg.PrimitiveTypes.Binary, []byte("foo"),
iceberg.BinaryLiteral([]byte("foo"))},
{
- iceberg.DecimalTypeOf(5, 2),
+ iceberg.MustDecimalTypeOf(5, 2),
[]byte{0x30, 0x39},
iceberg.DecimalLiteral{Scale: 2, Val:
decimal128.FromU64(12345)},
},
@@ -1642,7 +1642,7 @@ func TestRoundTripLiteralBinary(t *testing.T) {
// 1234567 is 00010010|11010110|10000111 in binary
// 00010010 -> 18, 11010110 -> 214, 10000111 -> 135
{
- iceberg.DecimalTypeOf(7, 4),
+ iceberg.MustDecimalTypeOf(7, 4),
[]byte{0x12, 0xd6, 0x87},
iceberg.DecimalLiteral{Scale: 4, Val:
decimal128.FromU64(1234567)},
},
@@ -1650,15 +1650,15 @@ func TestRoundTripLiteralBinary(t *testing.T) {
// -1234567 is 11101101|00101001|01111001 in binary
// 11101101 -> 237, 00101001 -> 41, 01111001 -> 121
{
- iceberg.DecimalTypeOf(7, 4),
+ iceberg.MustDecimalTypeOf(7, 4),
[]byte{0xed, 0x29, 0x79},
iceberg.DecimalLiteral{Scale: 4, Val:
decimal128.FromI64(-1234567)},
},
// test empty byte in decimal
// 11 is 00001011 in binary
// 00001011 -> 11
- {iceberg.DecimalTypeOf(10, 3), []byte{0x0b},
iceberg.DecimalLiteral{Scale: 3, Val: decimal128.FromU64(11)}},
- {iceberg.DecimalTypeOf(4, 2), []byte{0x04, 0xd2},
iceberg.DecimalLiteral{Scale: 2, Val: decimal128.FromU64(1234)}},
+ {iceberg.MustDecimalTypeOf(10, 3), []byte{0x0b},
iceberg.DecimalLiteral{Scale: 3, Val: decimal128.FromU64(11)}},
+ {iceberg.MustDecimalTypeOf(4, 2), []byte{0x04, 0xd2},
iceberg.DecimalLiteral{Scale: 2, Val: decimal128.FromU64(1234)}},
}
for _, tt := range tests {
@@ -1683,7 +1683,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
val string
}{
{
- iceberg.DecimalTypeOf(38, 21),
+ iceberg.MustDecimalTypeOf(38, 21),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0xe9, 0x18, 0x30,
0x73, 0xb9, 0x1e,
0x7e, 0xa2, 0xb3, 0x6a, 0x83,
@@ -1691,7 +1691,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"12345678912345678.123456789123456789123",
},
{
- iceberg.DecimalTypeOf(38, 22),
+ iceberg.MustDecimalTypeOf(38, 22),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0xe9, 0x16, 0xbb,
0x01, 0x2f,
0x4c, 0xc3, 0x2b, 0x42, 0x29, 0x22,
@@ -1699,7 +1699,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"1234567891234567.1234567891234567891234",
},
{
- iceberg.DecimalTypeOf(38, 23),
+ iceberg.MustDecimalTypeOf(38, 23),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0xe9, 0x0a, 0x42,
0xa1, 0xad,
0xe5, 0x2b, 0x33, 0x15, 0x9b, 0x59,
@@ -1707,7 +1707,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"123456789123456.12345678912345678912345",
},
{
- iceberg.DecimalTypeOf(38, 24),
+ iceberg.MustDecimalTypeOf(38, 24),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0xe8, 0xa2, 0xbb,
0xe9, 0x67,
0xba, 0x86, 0x77, 0xd8, 0x11, 0x80,
@@ -1715,7 +1715,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"12345678912345.123456789123456789123456",
},
{
- iceberg.DecimalTypeOf(38, 25),
+ iceberg.MustDecimalTypeOf(38, 25),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0xe5, 0x6b, 0x3a,
0xd2, 0x78,
0xdd, 0x04, 0xc8, 0x70, 0xaf, 0x07,
@@ -1723,7 +1723,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"1234567891234.1234567891234567891234567",
},
{
- iceberg.DecimalTypeOf(38, 26),
+ iceberg.MustDecimalTypeOf(38, 26),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0xcd, 0x85, 0xc5,
0x03, 0x38, 0x37,
0x3c, 0x38, 0x66, 0xd6, 0x4e,
@@ -1731,7 +1731,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"123456789123.12345678912345678912345678",
},
{
- iceberg.DecimalTypeOf(38, 27),
+ iceberg.MustDecimalTypeOf(38, 27),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0x31, 0x46, 0xfd,
0xc7, 0x79,
0xca, 0x39, 0x7c, 0x04, 0x5f, 0x15,
@@ -1739,7 +1739,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"12345678912.123456789123456789123456789",
},
{
- iceberg.DecimalTypeOf(38, 28),
+ iceberg.MustDecimalTypeOf(38, 28),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x10, 0x52, 0x01, 0x72,
0x11, 0xda,
0x08, 0x5b, 0x08, 0x2b, 0xb6, 0xd3,
@@ -1747,7 +1747,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"1234567891.1234567891234567891234567891",
},
{
- iceberg.DecimalTypeOf(38, 29),
+ iceberg.MustDecimalTypeOf(38, 29),
[]byte{
0x09, 0x49, 0xb0, 0xf7, 0x13, 0xe9, 0x18, 0x5b,
0x37, 0xc1,
0x78, 0x0b, 0x91, 0xb5, 0x24, 0x40,
@@ -1755,7 +1755,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"123456789.12345678912345678912345678912",
},
{
- iceberg.DecimalTypeOf(38, 30),
+ iceberg.MustDecimalTypeOf(38, 30),
[]byte{
0x09, 0x49, 0xb0, 0xed, 0x1e, 0xdf, 0x80, 0x03,
0x47, 0x3b,
0x16, 0x9b, 0xf1, 0x13, 0x6a, 0x83,
@@ -1763,7 +1763,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"12345678.123456789123456789123456789123",
},
{
- iceberg.DecimalTypeOf(38, 31),
+ iceberg.MustDecimalTypeOf(38, 31),
[]byte{
0x09, 0x49, 0xb0, 0x96, 0x2b, 0xac, 0x29, 0x64,
0x28, 0x70,
0x36, 0x29, 0xea, 0xc2, 0x29, 0x22,
@@ -1771,7 +1771,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"1234567.1234567891234567891234567891234",
},
{
- iceberg.DecimalTypeOf(38, 32),
+ iceberg.MustDecimalTypeOf(38, 32),
[]byte{
0x09, 0x49, 0xad, 0xae, 0xe3, 0x68, 0xe7, 0x4f,
0xb5, 0x14,
0xbc, 0xdc, 0x2b, 0x95, 0x9b, 0x59,
@@ -1779,7 +1779,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"123456.12345678912345678912345678912345",
},
{
- iceberg.DecimalTypeOf(38, 33),
+ iceberg.MustDecimalTypeOf(38, 33),
[]byte{
0x09, 0x49, 0x95, 0x94, 0x3e, 0x35, 0x93, 0xde,
0xb9, 0x2e,
0xef, 0x53, 0xb3, 0xd8, 0x11, 0x80,
@@ -1787,7 +1787,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"12345.123456789123456789123456789123456",
},
{
- iceberg.DecimalTypeOf(38, 34),
+ iceberg.MustDecimalTypeOf(38, 34),
[]byte{
0x09, 0x48, 0xd5, 0xd7, 0x90, 0x78, 0xdf, 0x08,
0x1a, 0xf6,
0x43, 0x09, 0x06, 0x70, 0xaf, 0x07,
@@ -1795,7 +1795,7 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"1234.1234567891234567891234567891234567",
},
{
- iceberg.DecimalTypeOf(38, 35),
+ iceberg.MustDecimalTypeOf(38, 35),
[]byte{
0x09, 0x43, 0x45, 0x82, 0x85, 0xc7, 0x56, 0x66,
0x24, 0x4d,
0x16, 0x82, 0x40, 0x66, 0xd6, 0x4e,
@@ -1803,57 +1803,57 @@ func TestLargeDecimalRoundTrip(t *testing.T) {
"123.12345678912345678912345678912345678",
},
{
- iceberg.DecimalTypeOf(21, 16),
+ iceberg.MustDecimalTypeOf(21, 16),
[]byte{0x06, 0xb1, 0x3a, 0xe3, 0xc4, 0x4e, 0x94, 0xaf,
0x07},
"12345.1234567891234567",
},
{
- iceberg.DecimalTypeOf(22, 17),
+ iceberg.MustDecimalTypeOf(22, 17),
[]byte{0x42, 0xec, 0x4c, 0xe5, 0xab, 0x11, 0xce, 0xd6,
0x4e},
"12345.12345678912345678",
},
{
- iceberg.DecimalTypeOf(23, 18),
+ iceberg.MustDecimalTypeOf(23, 18),
[]byte{0x02, 0x9d, 0x3b, 0x00, 0xf8, 0xae, 0xb2, 0x14,
0x5f, 0x15},
"12345.123456789123456789",
},
{
- iceberg.DecimalTypeOf(24, 19),
+ iceberg.MustDecimalTypeOf(24, 19),
[]byte{0x1a, 0x24, 0x4e, 0x09, 0xb6, 0xd2, 0xf4, 0xcb,
0xb6, 0xd3},
"12345.1234567891234567891",
},
{
- iceberg.DecimalTypeOf(25, 20),
+ iceberg.MustDecimalTypeOf(25, 20),
[]byte{0x01, 0x05, 0x6b, 0x0c, 0x61, 0x24, 0x3d, 0x8f,
0xf5, 0x24, 0x40},
"12345.12345678912345678912",
},
{
- iceberg.DecimalTypeOf(26, 21),
+ iceberg.MustDecimalTypeOf(26, 21),
[]byte{0x0a, 0x36, 0x2e, 0x7b, 0xcb, 0x6a, 0x67, 0x9f,
0x93, 0x6a, 0x83},
"12345.123456789123456789123",
},
{
- iceberg.DecimalTypeOf(27, 22),
+ iceberg.MustDecimalTypeOf(27, 22),
[]byte{0x66, 0x1d, 0xd0, 0xd5, 0xf2, 0x28, 0x0c, 0x3b,
0xc2, 0x29, 0x22},
"12345.1234567891234567891234",
},
{
- iceberg.DecimalTypeOf(28, 23),
+ iceberg.MustDecimalTypeOf(28, 23),
[]byte{0x03, 0xfd, 0x2a, 0x28, 0x5b, 0x75, 0x90, 0x7a,
0x55, 0x95, 0x9b, 0x59},
"12345.12345678912345678912345",
},
{
- iceberg.DecimalTypeOf(29, 24),
+ iceberg.MustDecimalTypeOf(29, 24),
[]byte{0x27, 0xe3, 0xa5, 0x93, 0x92, 0x97, 0xa4, 0xc7,
0x57, 0xd8, 0x11, 0x80},
"12345.123456789123456789123456",
},
{
- iceberg.DecimalTypeOf(30, 25),
+ iceberg.MustDecimalTypeOf(30, 25),
[]byte{0x01, 0x8e, 0xe4, 0x77, 0xc3, 0xb9, 0xec, 0x6f,
0xc9, 0x6e, 0x70, 0xaf, 0x07},
"12345.1234567891234567891234567",
},
{
- iceberg.DecimalTypeOf(31, 26),
+ iceberg.MustDecimalTypeOf(31, 26),
[]byte{0x0f, 0x94, 0xec, 0xad, 0xa5, 0x43, 0x3c, 0x5d,
0xde, 0x50, 0x66, 0xd6, 0x4e},
"12345.12345678912345678912345678",
},
@@ -1882,16 +1882,16 @@ func TestDecimalMaxMinRoundTrip(t *testing.T) {
typ iceberg.DecimalType
v string
}{
- {iceberg.DecimalTypeOf(6, 2), "9999.99"},
- {iceberg.DecimalTypeOf(10, 10), ".9999999999"},
- {iceberg.DecimalTypeOf(2, 1), "9.9"},
- {iceberg.DecimalTypeOf(38, 37),
"9.9999999999999999999999999999999999999"},
- {iceberg.DecimalTypeOf(20, 1), "9999999999999999999.9"},
- {iceberg.DecimalTypeOf(6, 2), "-9999.99"},
- {iceberg.DecimalTypeOf(10, 10), "-.9999999999"},
- {iceberg.DecimalTypeOf(2, 1), "-9.9"},
- {iceberg.DecimalTypeOf(38, 37),
"-9.9999999999999999999999999999999999999"},
- {iceberg.DecimalTypeOf(20, 1), "-9999999999999999999.9"},
+ {iceberg.MustDecimalTypeOf(6, 2), "9999.99"},
+ {iceberg.MustDecimalTypeOf(10, 10), ".9999999999"},
+ {iceberg.MustDecimalTypeOf(2, 1), "9.9"},
+ {iceberg.MustDecimalTypeOf(38, 37),
"9.9999999999999999999999999999999999999"},
+ {iceberg.MustDecimalTypeOf(20, 1), "9999999999999999999.9"},
+ {iceberg.MustDecimalTypeOf(6, 2), "-9999.99"},
+ {iceberg.MustDecimalTypeOf(10, 10), "-.9999999999"},
+ {iceberg.MustDecimalTypeOf(2, 1), "-9.9"},
+ {iceberg.MustDecimalTypeOf(38, 37),
"-9.9999999999999999999999999999999999999"},
+ {iceberg.MustDecimalTypeOf(20, 1), "-9999999999999999999.9"},
}
for _, tt := range tests {
diff --git a/manifest_partition_bench_test.go b/manifest_partition_bench_test.go
index a8e0cdc26..78b014371 100644
--- a/manifest_partition_bench_test.go
+++ b/manifest_partition_bench_test.go
@@ -40,9 +40,9 @@ func BenchmarkPartitionFieldStatsUpdate(b *testing.B) {
{name: "binary_repeated_16", typ: PrimitiveTypes.Binary,
pattern: "repeated", width: 16},
{name: "binary_cycling_64", typ: PrimitiveTypes.Binary,
pattern: "cycling", width: 64},
{name: "binary_monotonic_64", typ: PrimitiveTypes.Binary,
pattern: "monotonic", width: 64},
- {name: "fixed_repeated_16", typ: FixedTypeOf(16), pattern:
"repeated", width: 16},
- {name: "fixed_cycling_64", typ: FixedTypeOf(64), pattern:
"cycling", width: 64},
- {name: "fixed_monotonic_64", typ: FixedTypeOf(64), pattern:
"monotonic", width: 64},
+ {name: "fixed_repeated_16", typ: MustFixedTypeOf(16), pattern:
"repeated", width: 16},
+ {name: "fixed_cycling_64", typ: MustFixedTypeOf(64), pattern:
"cycling", width: 64},
+ {name: "fixed_monotonic_64", typ: MustFixedTypeOf(64), pattern:
"monotonic", width: 64},
} {
values := partitionFieldStatsBenchmarkValues(10_000, tc.width,
tc.pattern)
diff --git a/manifest_test.go b/manifest_test.go
index 41469ccd6..382be1353 100644
--- a/manifest_test.go
+++ b/manifest_test.go
@@ -532,7 +532,7 @@ func TestPartitionFieldStatsAcceptsConvertibleValues(t
*testing.T) {
{name: "time from duration", typ: PrimitiveTypes.Time, value:
time.Duration(11), want: NewLiteral(Time(11))},
{name: "timestamp from int64", typ: PrimitiveTypes.Timestamp,
value: int64(12), want: NewLiteral(Timestamp(12))},
{name: "binary from string", typ: PrimitiveTypes.Binary, value:
"shard", want: NewLiteral([]byte("shard"))},
- {name: "fixed from bytes", typ: FixedTypeOf(5), value: "fixed",
want: NewLiteral([]byte("fixed"))},
+ {name: "fixed from bytes", typ: MustFixedTypeOf(5), value:
"fixed", want: NewLiteral([]byte("fixed"))},
{
name: "uuid from array",
typ: PrimitiveTypes.UUID,
@@ -541,7 +541,7 @@ func TestPartitionFieldStatsAcceptsConvertibleValues(t
*testing.T) {
},
{
name: "decimal from decimal literal",
- typ: DecimalTypeOf(10, 2),
+ typ: MustDecimalTypeOf(10, 2),
value: DecimalLiteral{Val: decimal128.FromI64(130),
Scale: 2},
want: NewLiteral(Decimal{Val: decimal128.FromI64(130),
Scale: 2}),
},
@@ -590,8 +590,8 @@ func TestPartitionFieldStatsRejectsUnsupportedValues(t
*testing.T) {
{name: "timestamp with timezone", typ:
PrimitiveTypes.TimestampTz},
{name: "uuid", typ: PrimitiveTypes.UUID},
{name: "binary", typ: PrimitiveTypes.Binary},
- {name: "fixed", typ: FixedTypeOf(5)},
- {name: "decimal", typ: DecimalTypeOf(10, 2)},
+ {name: "fixed", typ: MustFixedTypeOf(5)},
+ {name: "decimal", typ: MustDecimalTypeOf(10, 2)},
}
for _, tt := range tests {
@@ -3202,7 +3202,7 @@ func
TestAvroEncodePartitionDataUsesDeclaredDecimalFixedSize(t *testing.T) {
func TestManifestRoundTripDecimalPartitionUsesSignedFixedSize(t *testing.T) {
schema := NewSchema(
0,
- NestedField{ID: 1, Name: "price", Type: DecimalTypeOf(10, 2)},
+ NestedField{ID: 1, Name: "price", Type: MustDecimalTypeOf(10,
2)},
)
partitionSpec := NewPartitionSpecID(
1,
diff --git a/partitions_test.go b/partitions_test.go
index 274dfe042..a91c48413 100644
--- a/partitions_test.go
+++ b/partitions_test.go
@@ -529,7 +529,7 @@ func TestPartitionTypePreservesFieldOrderAndResultTypes(t
*testing.T) {
{ID: 2, Name: "nested", Type: iceberg.Int64Type{},
Required: true},
}}},
iceberg.NestedField{ID: 3, Name: "ts", Type:
iceberg.TimestampTzNsType{}, Required: true},
- iceberg.NestedField{ID: 4, Name: "amount", Type:
iceberg.DecimalTypeOf(12, 2)},
+ iceberg.NestedField{ID: 4, Name: "amount", Type:
iceberg.MustDecimalTypeOf(12, 2)},
)
unknown, err := iceberg.ParseTransform("custom_transform[42]")
require.NoError(t, err)
@@ -549,7 +549,7 @@ func TestPartitionTypePreservesFieldOrderAndResultTypes(t
*testing.T) {
want := []iceberg.NestedField{
{ID: 1007, Name: "nested", Type: iceberg.Int64Type{}},
{ID: 1001, Name: "ts", Type: iceberg.TimestampTzNsType{}},
- {ID: 1006, Name: "amount", Type: iceberg.DecimalTypeOf(12, 2)},
+ {ID: 1006, Name: "amount", Type: iceberg.MustDecimalTypeOf(12,
2)},
{ID: 1002, Name: "missing_bucket", Type: iceberg.Int32Type{}},
{ID: 1005, Name: "missing_day", Type: iceberg.DateType{}},
{ID: 1003, Name: "missing_identity", Type:
iceberg.UnknownType{}},
diff --git a/schema_compatibility_test.go b/schema_compatibility_test.go
index 6fbde7983..af16e89f1 100644
--- a/schema_compatibility_test.go
+++ b/schema_compatibility_test.go
@@ -55,12 +55,12 @@ func compatPrimitives(t *testing.T) []iceberg.PrimitiveType
{
iceberg.PrimitiveTypes.TimestampTzNs,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.UUID,
- iceberg.FixedTypeOf(3),
- iceberg.FixedTypeOf(4),
+ iceberg.MustFixedTypeOf(3),
+ iceberg.MustFixedTypeOf(4),
iceberg.PrimitiveTypes.Binary,
- iceberg.DecimalTypeOf(9, 2),
- iceberg.DecimalTypeOf(11, 2),
- iceberg.DecimalTypeOf(9, 3),
+ iceberg.MustDecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(11, 2),
+ iceberg.MustDecimalTypeOf(9, 3),
geomCRS84,
geom3857,
geogCRS84,
@@ -139,11 +139,11 @@ func TestIsPromotionAllowed(t *testing.T) {
{iceberg.PrimitiveTypes.Int64, iceberg.PrimitiveTypes.Int32,
false},
{iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64, true},
{iceberg.PrimitiveTypes.Float64,
iceberg.PrimitiveTypes.Float32, false},
- {iceberg.DecimalTypeOf(9, 2), iceberg.DecimalTypeOf(11, 2),
true},
- {iceberg.DecimalTypeOf(11, 2), iceberg.DecimalTypeOf(9, 2),
false},
- {iceberg.DecimalTypeOf(9, 2), iceberg.DecimalTypeOf(9, 3),
false},
+ {iceberg.MustDecimalTypeOf(9, 2), iceberg.MustDecimalTypeOf(11,
2), true},
+ {iceberg.MustDecimalTypeOf(11, 2), iceberg.MustDecimalTypeOf(9,
2), false},
+ {iceberg.MustDecimalTypeOf(9, 2), iceberg.MustDecimalTypeOf(9,
3), false},
{iceberg.PrimitiveTypes.String, iceberg.PrimitiveTypes.Binary,
false},
- {iceberg.FixedTypeOf(16), iceberg.PrimitiveTypes.UUID, false},
+ {iceberg.MustFixedTypeOf(16), iceberg.PrimitiveTypes.UUID,
false},
{iceberg.PrimitiveTypes.Date, iceberg.PrimitiveTypes.Timestamp,
false},
}
diff --git a/table/arrow_filter_plan_key_test.go
b/table/arrow_filter_plan_key_test.go
index 838cc51cb..a3878c605 100644
--- a/table/arrow_filter_plan_key_test.go
+++ b/table/arrow_filter_plan_key_test.go
@@ -42,11 +42,11 @@ func TestPhysicalSchemaKeyDistinctTypeTags(t *testing.T) {
iceberg.BinaryType{},
iceberg.UnknownType{},
iceberg.VariantType{},
- iceberg.FixedTypeOf(8),
- iceberg.FixedTypeOf(16),
- iceberg.DecimalTypeOf(10, 2),
- iceberg.DecimalTypeOf(11, 2),
- iceberg.DecimalTypeOf(10, 3),
+ iceberg.MustFixedTypeOf(8),
+ iceberg.MustFixedTypeOf(16),
+ iceberg.MustDecimalTypeOf(10, 2),
+ iceberg.MustDecimalTypeOf(11, 2),
+ iceberg.MustDecimalTypeOf(10, 3),
}
keys := make(map[string]string, len(types))
for _, typ := range types {
diff --git a/table/arrow_filter_plan_test.go b/table/arrow_filter_plan_test.go
index c96e726de..a33290d24 100644
--- a/table/arrow_filter_plan_test.go
+++ b/table/arrow_filter_plan_test.go
@@ -236,9 +236,9 @@ func TestPhysicalSchemaKeyDistinguishesNestedLayouts(t
*testing.T) {
}},
{ID: 4, Name: "lookup", Type: &iceberg.MapType{
KeyID: 5, KeyType:
iceberg.PrimitiveTypes.String,
- ValueID: 6, ValueType:
iceberg.DecimalTypeOf(10, 2),
+ ValueID: 6, ValueType:
iceberg.MustDecimalTypeOf(10, 2),
}},
- {ID: 7, Name: "fixed", Type: iceberg.FixedTypeOf(8)},
+ {ID: 7, Name: "fixed", Type:
iceberg.MustFixedTypeOf(8)},
{ID: 8, Name: "variant", Type: iceberg.VariantType{}},
}},
})
@@ -265,12 +265,12 @@ func TestPhysicalSchemaKeyDistinguishesNestedLayouts(t
*testing.T) {
{"map_value_id", func(s *iceberg.StructType) {
s.FieldList[1].Type.(*iceberg.MapType).ValueID = 60 }},
{"map_value_required", func(s *iceberg.StructType) {
s.FieldList[1].Type.(*iceberg.MapType).ValueRequired = true }},
{"decimal_precision", func(s *iceberg.StructType) {
- s.FieldList[1].Type.(*iceberg.MapType).ValueType =
iceberg.DecimalTypeOf(11, 2)
+ s.FieldList[1].Type.(*iceberg.MapType).ValueType =
iceberg.MustDecimalTypeOf(11, 2)
}},
{"decimal_scale", func(s *iceberg.StructType) {
- s.FieldList[1].Type.(*iceberg.MapType).ValueType =
iceberg.DecimalTypeOf(10, 3)
+ s.FieldList[1].Type.(*iceberg.MapType).ValueType =
iceberg.MustDecimalTypeOf(10, 3)
}},
- {"fixed_size", func(s *iceberg.StructType) {
s.FieldList[2].Type = iceberg.FixedTypeOf(16) }},
+ {"fixed_size", func(s *iceberg.StructType) {
s.FieldList[2].Type = iceberg.MustFixedTypeOf(16) }},
{"variant_type", func(s *iceberg.StructType) {
s.FieldList[3].Type = iceberg.PrimitiveTypes.Binary }},
{"empty_struct", func(s *iceberg.StructType) { s.FieldList =
nil }},
} {
diff --git a/table/arrow_scanner_bench_test.go
b/table/arrow_scanner_bench_test.go
index f0cdeff7b..5a945d7ea 100644
--- a/table/arrow_scanner_bench_test.go
+++ b/table/arrow_scanner_bench_test.go
@@ -512,8 +512,8 @@ func benchmarkPhysicalSchemaCases() []struct {
{ID: 1, Name: "flag", Type: iceberg.PrimitiveTypes.Bool},
{ID: 2, Name: "count", Type: iceberg.PrimitiveTypes.Int32},
{ID: 3, Name: "ratio", Type: iceberg.PrimitiveTypes.Float64},
- {ID: 4, Name: "fixed", Type: iceberg.FixedTypeOf(16)},
- {ID: 5, Name: "price", Type: iceberg.DecimalTypeOf(20, 4)},
+ {ID: 4, Name: "fixed", Type: iceberg.MustFixedTypeOf(16)},
+ {ID: 5, Name: "price", Type: iceberg.MustDecimalTypeOf(20, 4)},
{ID: 6, Name: "created", Type:
iceberg.PrimitiveTypes.TimestampTzNs},
{ID: 7, Name: "payload", Type: iceberg.VariantType{}},
{ID: 8, Name: "tags", Type: &iceberg.ListType{
diff --git a/table/arrow_utils.go b/table/arrow_utils.go
index b76cbd017..1cc15095e 100644
--- a/table/arrow_utils.go
+++ b/table/arrow_utils.go
@@ -393,7 +393,7 @@ func (c convertToIceberg) Primitive(dt arrow.DataType)
(result iceberg.NestedFie
result.Type = iceberg.PrimitiveTypes.Float64
case *arrow.Decimal32Type, *arrow.Decimal64Type, *arrow.Decimal128Type:
dec := dt.(arrow.DecimalType)
- result.Type = iceberg.DecimalTypeOf(int(dec.GetPrecision()),
int(dec.GetScale()))
+ result.Type =
iceberg.MustDecimalTypeOf(int(dec.GetPrecision()), int(dec.GetScale()))
case *arrow.StringType, *arrow.LargeStringType:
result.Type = iceberg.PrimitiveTypes.String
case *arrow.BinaryType, *arrow.LargeBinaryType:
@@ -431,7 +431,7 @@ func (c convertToIceberg) Primitive(dt arrow.DataType)
(result iceberg.NestedFie
panic(fmt.Errorf("%w: unsupported arrow type for
conversion - %s", iceberg.ErrInvalidSchema, dt))
}
case *arrow.FixedSizeBinaryType:
- result.Type = iceberg.FixedTypeOf(dt.ByteWidth)
+ result.Type = iceberg.MustFixedTypeOf(dt.ByteWidth)
case arrow.ExtensionType:
switch dt.ExtensionName() {
case "arrow.uuid":
diff --git a/table/arrow_utils_test.go b/table/arrow_utils_test.go
index 621d963ad..34be5b0d4 100644
--- a/table/arrow_utils_test.go
+++ b/table/arrow_utils_test.go
@@ -59,12 +59,12 @@ func TestArrowToIceberg(t *testing.T) {
reciprocal bool
err string
}{
- {&arrow.FixedSizeBinaryType{ByteWidth: 0},
iceberg.FixedTypeOf(0), true, ""},
- {&arrow.FixedSizeBinaryType{ByteWidth: 23},
iceberg.FixedTypeOf(23), true, ""},
- {&arrow.Decimal32Type{Precision: 8, Scale: 2},
iceberg.DecimalTypeOf(8, 2), false, ""},
+ {&arrow.FixedSizeBinaryType{ByteWidth: 0},
iceberg.MustFixedTypeOf(0), true, ""},
+ {&arrow.FixedSizeBinaryType{ByteWidth: 23},
iceberg.MustFixedTypeOf(23), true, ""},
+ {&arrow.Decimal32Type{Precision: 8, Scale: 2},
iceberg.MustDecimalTypeOf(8, 2), false, ""},
{&arrow.Decimal32Type{Precision: 8, Scale: 9}, nil, false,
"invalid scale 9: must be less than or equal to precision 8"},
- {&arrow.Decimal64Type{Precision: 15, Scale: 14},
iceberg.DecimalTypeOf(15, 14), false, ""},
- {&arrow.Decimal128Type{Precision: 26, Scale: 20},
iceberg.DecimalTypeOf(26, 20), true, ""},
+ {&arrow.Decimal64Type{Precision: 15, Scale: 14},
iceberg.MustDecimalTypeOf(15, 14), false, ""},
+ {&arrow.Decimal128Type{Precision: 26, Scale: 20},
iceberg.MustDecimalTypeOf(26, 20), true, ""},
{&arrow.Decimal256Type{Precision: 8, Scale: 9}, nil, false,
"unsupported arrow type for conversion - decimal256(8, 9)"},
{arrow.FixedWidthTypes.Boolean, iceberg.PrimitiveTypes.Bool,
true, ""},
{arrow.Null, iceberg.PrimitiveTypes.Unknown, true, ""},
@@ -1830,7 +1830,7 @@ func TestToRequestedSchemaWriteDefaultsTypes(t
*testing.T) {
{
name: "decimal write-default",
field: iceberg.NestedField{
- ID: 2, Name: "price", Type:
iceberg.DecimalTypeOf(10, 2),
+ ID: 2, Name: "price", Type:
iceberg.MustDecimalTypeOf(10, 2),
Required: false, WriteDefault:
iceberg.Decimal{Val: decimal128.New(0, 12345), Scale: 2},
},
check: func(t *testing.T, col arrow.Array) {
@@ -2059,7 +2059,7 @@ func TestToRequestedSchemaInitialDefaultTypes(t
*testing.T) {
{
name: "decimal initial-default",
field: iceberg.NestedField{
- ID: 2, Name: "price", Type:
iceberg.DecimalTypeOf(10, 2),
+ ID: 2, Name: "price", Type:
iceberg.MustDecimalTypeOf(10, 2),
Required: false, InitialDefault:
iceberg.Decimal{Val: decimal128.New(0, 12345), Scale: 2},
},
check: func(t *testing.T, col arrow.Array) {
diff --git a/table/equality_delete_index_metrics_test.go
b/table/equality_delete_index_metrics_test.go
index 757236c3a..4a388c2d7 100644
--- a/table/equality_delete_index_metrics_test.go
+++ b/table/equality_delete_index_metrics_test.go
@@ -340,13 +340,13 @@ func
TestEqualityDeleteIndexDoesNotUseUncertainFloatBounds(t *testing.T) {
}
func TestEqualityDeleteMetricValueCompareSupportsRangeTypes(t *testing.T) {
- decimalLower, err := iceberg.LiteralFromBytes(iceberg.DecimalTypeOf(9,
0), []byte{1})
+ decimalLower, err :=
iceberg.LiteralFromBytes(iceberg.MustDecimalTypeOf(9, 0), []byte{1})
require.NoError(t, err)
- decimalUpper, err := iceberg.LiteralFromBytes(iceberg.DecimalTypeOf(9,
0), []byte{2})
+ decimalUpper, err :=
iceberg.LiteralFromBytes(iceberg.MustDecimalTypeOf(9, 0), []byte{2})
require.NoError(t, err)
- fixedLower, err := iceberg.LiteralFromBytes(iceberg.FixedTypeOf(2),
[]byte{1, 0})
+ fixedLower, err := iceberg.LiteralFromBytes(iceberg.MustFixedTypeOf(2),
[]byte{1, 0})
require.NoError(t, err)
- fixedUpper, err := iceberg.LiteralFromBytes(iceberg.FixedTypeOf(2),
[]byte{2, 0})
+ fixedUpper, err := iceberg.LiteralFromBytes(iceberg.MustFixedTypeOf(2),
[]byte{2, 0})
require.NoError(t, err)
tests := []struct {
@@ -366,13 +366,13 @@ func
TestEqualityDeleteMetricValueCompareSupportsRangeTypes(t *testing.T) {
{"timestamp-nano", iceberg.PrimitiveTypes.TimestampNs,
iceberg.NewLiteral(iceberg.TimestampNano(1)),
iceberg.NewLiteral(iceberg.TimestampNano(2))},
{"string", iceberg.PrimitiveTypes.String,
iceberg.NewLiteral("a"), iceberg.NewLiteral("b")},
{"binary", iceberg.PrimitiveTypes.Binary,
iceberg.NewLiteral([]byte{1}), iceberg.NewLiteral([]byte{2})},
- {"fixed", iceberg.FixedTypeOf(2), fixedLower, fixedUpper},
+ {"fixed", iceberg.MustFixedTypeOf(2), fixedLower, fixedUpper},
{
"uuid", iceberg.PrimitiveTypes.UUID,
iceberg.NewLiteral(uuid.MustParse("00000000-0000-0000-0000-000000000001")),
iceberg.NewLiteral(uuid.MustParse("00000000-0000-0000-0000-000000000002")),
},
- {"decimal", iceberg.DecimalTypeOf(9, 0), decimalLower,
decimalUpper},
+ {"decimal", iceberg.MustDecimalTypeOf(9, 0), decimalLower,
decimalUpper},
}
for _, tt := range tests {
diff --git a/table/equality_delete_writer_test.go
b/table/equality_delete_writer_test.go
index 436cfcb1a..8db449fa3 100644
--- a/table/equality_delete_writer_test.go
+++ b/table/equality_delete_writer_test.go
@@ -354,7 +354,7 @@ func newPartitionedEqDeleteTestTable(t *testing.T)
*table.Table {
iceberg.NestedField{ID: 1, Name: "id", Type:
iceberg.PrimitiveTypes.Int64, Required: true},
iceberg.NestedField{ID: 2, Name: "category", Type:
iceberg.PrimitiveTypes.String, Required: true},
iceberg.NestedField{ID: 3, Name: "score", Type:
iceberg.PrimitiveTypes.Float32, Required: false},
- iceberg.NestedField{ID: 4, Name: "price", Type:
iceberg.DecimalTypeOf(10, 2), Required: false},
+ iceberg.NestedField{ID: 4, Name: "price", Type:
iceberg.MustDecimalTypeOf(10, 2), Required: false},
)
partSpec := iceberg.NewPartitionSpec(
@@ -447,7 +447,7 @@ func
TestWriteEqualityDeleteFilesPartitionedTableAcceptsDecimalFieldID(t *testin
tbl := newPartitionedEqDeleteTestTable(t)
delSchema := iceberg.NewSchema(0,
- iceberg.NestedField{ID: 4, Name: "price", Type:
iceberg.DecimalTypeOf(10, 2), Required: false},
+ iceberg.NestedField{ID: 4, Name: "price", Type:
iceberg.MustDecimalTypeOf(10, 2), Required: false},
iceberg.NestedField{ID: 2, Name: "category", Type:
iceberg.PrimitiveTypes.String, Required: true},
)
delArrowSc, err := table.SchemaToArrowSchema(delSchema, nil, true,
false)
diff --git a/table/evaluators_invalid_bounds_test.go
b/table/evaluators_invalid_bounds_test.go
index a79d01d46..93ea9c02f 100644
--- a/table/evaluators_invalid_bounds_test.go
+++ b/table/evaluators_invalid_bounds_test.go
@@ -26,7 +26,7 @@ import (
func TestMalformedFixedBoundsAreConservative(t *testing.T) {
schema := iceberg.NewSchema(1, iceberg.NestedField{
- ID: 1, Name: "value", Type: iceberg.FixedTypeOf(4),
+ ID: 1, Name: "value", Type: iceberg.MustFixedTypeOf(4),
})
expr := iceberg.EqualTo(iceberg.Reference("value"), []byte{1, 2, 3, 4})
malformed := []byte{1, 2, 3, 4, 5}
diff --git a/table/evaluators_row_group_test.go
b/table/evaluators_row_group_test.go
index 3ede72b98..a010b976c 100644
--- a/table/evaluators_row_group_test.go
+++ b/table/evaluators_row_group_test.go
@@ -209,7 +209,7 @@ func TestInclusiveMetricsEvalIntBackedDecimalRowGroup(t
*testing.T) {
minUnscaled, maxUnscaled := rng.minUnscaled,
rng.maxUnscaled
meta := buildDecimalRowGroupMetadata(t,
tt.physical, tt.typeLen,
int32(tt.precision), scale,
tt.encode(minUnscaled), tt.encode(maxUnscaled))
- field := iceberg.DecimalTypeOf(tt.precision,
scale)
+ field :=
iceberg.MustDecimalTypeOf(tt.precision, scale)
ref := iceberg.Reference("decimal")
keep := func(pred iceberg.BooleanExpression)
bool {
@@ -288,7 +288,7 @@ func TestInclusiveMetricsEvalRealParquetDecimalRowGroup(t
*testing.T) {
require.True(t, intBackedDecimal(stats.Descr()),
"writer did not produce an INT32-backed decimal, so this test
no longer covers the bug")
- field := iceberg.DecimalTypeOf(precision, scale)
+ field := iceberg.MustDecimalTypeOf(precision, scale)
ref := iceberg.Reference("decimal")
schema := iceberg.NewSchema(0, iceberg.NestedField{
ID: 1, Name: "decimal", Type: field, Required: true,
diff --git a/table/in_predicate_extrema_bench_test.go
b/table/in_predicate_extrema_bench_test.go
index 0cfe2da9d..293269b74 100644
--- a/table/in_predicate_extrema_bench_test.go
+++ b/table/in_predicate_extrema_bench_test.go
@@ -71,13 +71,13 @@ func BenchmarkManifestEvaluatorInPredicate(b *testing.B) {
}
b.Run("pruned-lower", func(b *testing.B) {
- benchmarkManifestIn(b, values,
iceberg.Decimal{Val: decimal128.FromI64(int64(literalCount+1) * 100), Scale:
2}, iceberg.Decimal{Val: decimal128.FromI64(int64(literalCount+1) * 100),
Scale: 2}, iceberg.DecimalTypeOf(12, 2))
+ benchmarkManifestIn(b, values,
iceberg.Decimal{Val: decimal128.FromI64(int64(literalCount+1) * 100), Scale:
2}, iceberg.Decimal{Val: decimal128.FromI64(int64(literalCount+1) * 100),
Scale: 2}, iceberg.MustDecimalTypeOf(12, 2))
})
b.Run("pruned-upper", func(b *testing.B) {
- benchmarkManifestIn(b, values,
iceberg.Decimal{Val: decimal128.FromI64(-100), Scale: 2}, iceberg.Decimal{Val:
decimal128.FromI64(-100), Scale: 2}, iceberg.DecimalTypeOf(12, 2))
+ benchmarkManifestIn(b, values,
iceberg.Decimal{Val: decimal128.FromI64(-100), Scale: 2}, iceberg.Decimal{Val:
decimal128.FromI64(-100), Scale: 2}, iceberg.MustDecimalTypeOf(12, 2))
})
b.Run("no-prune", func(b *testing.B) {
- benchmarkManifestIn(b, values,
iceberg.Decimal{Val: decimal128.FromI64(-100), Scale: 2}, iceberg.Decimal{Val:
decimal128.FromI64(int64(literalCount+1) * 100), Scale: 2},
iceberg.DecimalTypeOf(12, 2))
+ benchmarkManifestIn(b, values,
iceberg.Decimal{Val: decimal128.FromI64(-100), Scale: 2}, iceberg.Decimal{Val:
decimal128.FromI64(int64(literalCount+1) * 100), Scale: 2},
iceberg.MustDecimalTypeOf(12, 2))
})
})
}
@@ -132,7 +132,7 @@ func BenchmarkInclusiveMetricsEvalInPredicate(b *testing.B)
{
// Keep lexical and numeric order identical,
including the below-set bound.
return
iceberg.NewLiteral(fmt.Sprintf("value-%06d", value+1000))
}},
- {"decimal", iceberg.DecimalTypeOf(12, 2), func(value
int) iceberg.Literal {
+ {"decimal", iceberg.MustDecimalTypeOf(12, 2),
func(value int) iceberg.Literal {
return iceberg.NewLiteral(iceberg.Decimal{Val:
decimal128.FromI64(int64(value)), Scale: 2})
}},
} {
diff --git a/table/in_predicate_extrema_test.go
b/table/in_predicate_extrema_test.go
index 59397deaf..04b135dc8 100644
--- a/table/in_predicate_extrema_test.go
+++ b/table/in_predicate_extrema_test.go
@@ -85,7 +85,7 @@ func TestManifestEvaluatorInPredicateExtrema(t *testing.T) {
tests := []testCase{
{
name: "decimal below lower bound",
- typ: iceberg.DecimalTypeOf(12, 2),
+ typ: iceberg.MustDecimalTypeOf(12, 2),
expr: iceberg.IsIn(iceberg.Reference("value"),
decimal(100), decimal(200), decimal(300)),
lower: iceberg.NewLiteral(decimal(400)),
upper: iceberg.NewLiteral(decimal(500)),
@@ -93,7 +93,7 @@ func TestManifestEvaluatorInPredicateExtrema(t *testing.T) {
},
{
name: "decimal above upper bound",
- typ: iceberg.DecimalTypeOf(12, 2),
+ typ: iceberg.MustDecimalTypeOf(12, 2),
expr: iceberg.IsIn(iceberg.Reference("value"),
decimal(100), decimal(200), decimal(300)),
lower: iceberg.NewLiteral(decimal(-100)),
upper: iceberg.NewLiteral(decimal(0)),
@@ -101,7 +101,7 @@ func TestManifestEvaluatorInPredicateExtrema(t *testing.T) {
},
{
name: "decimal overlaps bound",
- typ: iceberg.DecimalTypeOf(12, 2),
+ typ: iceberg.MustDecimalTypeOf(12, 2),
expr: iceberg.IsIn(iceberg.Reference("value"),
decimal(100), decimal(200), decimal(300)),
lower: iceberg.NewLiteral(decimal(200)),
upper: iceberg.NewLiteral(decimal(250)),
@@ -328,14 +328,14 @@ func
TestInclusiveMetricsEvaluatorInPredicateExtremaFastPathTypes(t *testing.T)
},
{
name: "decimal upper disjoint",
- typ: iceberg.DecimalTypeOf(12, 2),
+ typ: iceberg.MustDecimalTypeOf(12, 2),
expr: iceberg.IsIn(iceberg.Reference("value"),
decimal(100), decimal(200)),
minLit: iceberg.NewLiteral(decimal(100)), maxLit:
iceberg.NewLiteral(decimal(200)),
lower: iceberg.NewLiteral(decimal(-200)), upper:
iceberg.NewLiteral(decimal(0)),
},
{
name: "decimal overlaps",
- typ: iceberg.DecimalTypeOf(12, 2),
+ typ: iceberg.MustDecimalTypeOf(12, 2),
expr: iceberg.IsIn(iceberg.Reference("value"),
decimal(100), decimal(200)),
minLit: iceberg.NewLiteral(decimal(100)), maxLit:
iceberg.NewLiteral(decimal(200)),
lower: iceberg.NewLiteral(decimal(100)), upper:
iceberg.NewLiteral(decimal(150)),
@@ -456,7 +456,7 @@ func
TestInclusiveMetricsEvaluatorInPredicateExtremaUsesFastPath(t *testing.T) {
iceberg.NewLiteral("a"), iceberg.NewLiteral("b"),
},
{
- "decimal", iceberg.DecimalTypeOf(12, 2),
+ "decimal", iceberg.MustDecimalTypeOf(12, 2),
[]iceberg.Literal{iceberg.NewLiteral(decimal(5000)),
iceberg.NewLiteral(decimal(6000))},
iceberg.NewLiteral(decimal(100)),
iceberg.NewLiteral(decimal(200)),
},
diff --git a/table/inspect_internal_test.go b/table/inspect_internal_test.go
index 1b26c60e3..fd91c12bf 100644
--- a/table/inspect_internal_test.go
+++ b/table/inspect_internal_test.go
@@ -3326,7 +3326,7 @@ func
TestInspectPositionDeletesParquetProjectsEvolvedNestedRow(t *testing.T) {
tableSchema := iceberg.NewSchema(0,
iceberg.NestedField{ID: 1, Name: "values", Type: tableListType,
Required: true},
iceberg.NestedField{ID: 2, Name: "attributes", Type:
tableMapType, Required: true},
- iceberg.NestedField{ID: 6, Name: "amount", Type:
iceberg.DecimalTypeOf(18, 2), Required: true},
+ iceberg.NestedField{ID: 6, Name: "amount", Type:
iceberg.MustDecimalTypeOf(18, 2), Required: true},
)
sourceListType := arrow.ListOfField(arrow.Field{
@@ -3846,7 +3846,7 @@ func
TestPositionDeleteRowProjectionPromotesNestedValues(t *testing.T) {
tableSchema := iceberg.NewSchema(0,
iceberg.NestedField{ID: 1, Name: "values", Type: tableListType,
Required: true},
iceberg.NestedField{ID: 2, Name: "attributes", Type:
tableMapType, Required: true},
- iceberg.NestedField{ID: 6, Name: "amount", Type:
iceberg.DecimalTypeOf(18, 2), Required: true},
+ iceberg.NestedField{ID: 6, Name: "amount", Type:
iceberg.MustDecimalTypeOf(18, 2), Required: true},
)
outputSchema, err := SchemaToArrowSchema(
PositionDeletesSchema(tableSchema, &iceberg.StructType{}, 2),
nil, true, false)
@@ -4269,7 +4269,7 @@ func testFieldNames(sc *iceberg.Schema) []string {
}
func TestInspectValueScalarDecimal(t *testing.T) {
- typ := iceberg.DecimalTypeOf(10, 2)
+ typ := iceberg.MustDecimalTypeOf(10, 2)
arrowType := &arrow.Decimal128Type{Precision: 10, Scale: 2}
value := iceberg.DecimalLiteral{Val: decimal128.FromI64(123), Scale: 2}
diff --git a/table/inspect_partition_append_test.go
b/table/inspect_partition_append_test.go
index 1706f3431..0ecab8502 100644
--- a/table/inspect_partition_append_test.go
+++ b/table/inspect_partition_append_test.go
@@ -126,7 +126,7 @@ func
TestInspectPartitionBuilderAppendsTypedAndFallbackValues(t *testing.T) {
},
{
name: "decimal scalar fallback",
- typ: iceberg.DecimalTypeOf(10, 2),
+ typ: iceberg.MustDecimalTypeOf(10, 2),
value: iceberg.DecimalLiteral{Val:
decimal128.FromI64(123), Scale: 2},
check: func(t *testing.T, value arrow.Array) {
require.Equal(t, decimal128.FromI64(123),
value.(*array.Decimal128).Value(0))
@@ -134,7 +134,7 @@ func
TestInspectPartitionBuilderAppendsTypedAndFallbackValues(t *testing.T) {
},
{
name: "fixed scalar fallback",
- typ: iceberg.FixedTypeOf(3),
+ typ: iceberg.MustFixedTypeOf(3),
value: []byte("abc"),
check: func(t *testing.T, value arrow.Array) {
require.Equal(t, []byte("abc"),
value.(*array.FixedSizeBinary).Value(0))
@@ -181,7 +181,7 @@ func
TestInspectPartitionBuilderScalarFallbackPreservesValidation(t *testing.T)
{name: "compatible integer string", typ:
iceberg.PrimitiveTypes.Int32, value: "42"},
{name: "invalid integer string", typ:
iceberg.PrimitiveTypes.Int32, value: "not-an-int", wantErr: "partition field
\"value\": strconv.ParseInt"},
{name: "wrong date value", typ: iceberg.PrimitiveTypes.Date,
value: int64(1), wantErr: "partition field \"value\": unsupported date"},
- {name: "wrong fixed width", typ: iceberg.FixedTypeOf(2), value:
[]byte("x"), wantErr: "invalid scalar value of len"},
+ {name: "wrong fixed width", typ: iceberg.MustFixedTypeOf(2),
value: []byte("x"), wantErr: "invalid scalar value of len"},
}
for _, tt := range tests {
diff --git a/table/internal/parquet_files_test.go
b/table/internal/parquet_files_test.go
index 5effcffdf..e98a4703e 100644
--- a/table/internal/parquet_files_test.go
+++ b/table/internal/parquet_files_test.go
@@ -467,19 +467,19 @@ func getCollector() map[int]internal.StatisticsCollector {
FieldID: 13,
Mode: modeFull,
ColName: "small_dec",
- IcebergTyp: iceberg.DecimalTypeOf(8, 2),
+ IcebergTyp: iceberg.MustDecimalTypeOf(8, 2),
},
14: {
FieldID: 14,
Mode: modeFull,
ColName: "med_dec",
- IcebergTyp: iceberg.DecimalTypeOf(16, 2),
+ IcebergTyp: iceberg.MustDecimalTypeOf(16, 2),
},
15: {
FieldID: 15,
Mode: modeFull,
ColName: "large_dec",
- IcebergTyp: iceberg.DecimalTypeOf(24, 2),
+ IcebergTyp: iceberg.MustDecimalTypeOf(24, 2),
},
}
}
@@ -588,16 +588,16 @@ func TestMetricsPrimitiveTypes(t *testing.T) {
assertBounds(t, df.LowerBoundValues()[11], iceberg.PrimitiveTypes.UUID,
uuid.NewMD5(uuid.NameSpaceDNS, []byte("foo")))
assertBounds(t, df.LowerBoundValues()[12],
iceberg.PrimitiveTypes.Binary, []byte("he"))
- assertBounds(t, df.LowerBoundValues()[13], iceberg.DecimalTypeOf(8, 2),
iceberg.Decimal{
+ assertBounds(t, df.LowerBoundValues()[13], iceberg.MustDecimalTypeOf(8,
2), iceberg.Decimal{
Val: decimal128.FromI64(12345678),
Scale: 2,
})
- assertBounds(t, df.LowerBoundValues()[14], iceberg.DecimalTypeOf(16,
2), iceberg.Decimal{
+ assertBounds(t, df.LowerBoundValues()[14],
iceberg.MustDecimalTypeOf(16, 2), iceberg.Decimal{
Val: decimal128.FromI64(1234567890123456),
Scale: 2,
})
expected, _ := (&big.Int{}).SetString("123456789012345678901234", 10)
- assertBounds(t, df.LowerBoundValues()[15], iceberg.DecimalTypeOf(24,
2), iceberg.Decimal{
+ assertBounds(t, df.LowerBoundValues()[15],
iceberg.MustDecimalTypeOf(24, 2), iceberg.Decimal{
Val: decimal128.FromBigInt(expected),
Scale: 2,
})
@@ -620,16 +620,16 @@ func TestMetricsPrimitiveTypes(t *testing.T) {
assertBounds(t, df.UpperBoundValues()[11], iceberg.PrimitiveTypes.UUID,
uuid.NewMD5(uuid.NameSpaceDNS, []byte("bar")))
assertBounds(t, df.UpperBoundValues()[12],
iceberg.PrimitiveTypes.Binary, []byte("wp"))
- assertBounds(t, df.UpperBoundValues()[13], iceberg.DecimalTypeOf(8, 2),
iceberg.Decimal{
+ assertBounds(t, df.UpperBoundValues()[13], iceberg.MustDecimalTypeOf(8,
2), iceberg.Decimal{
Val: decimal128.FromI64(87654321),
Scale: 2,
})
- assertBounds(t, df.UpperBoundValues()[14], iceberg.DecimalTypeOf(16,
2), iceberg.Decimal{
+ assertBounds(t, df.UpperBoundValues()[14],
iceberg.MustDecimalTypeOf(16, 2), iceberg.Decimal{
Val: decimal128.FromI64(6543210987654321),
Scale: 2,
})
expectedUpper, _ := (&big.Int{}).SetString("432109876543210987654321",
10)
- assertBounds(t, df.UpperBoundValues()[15], iceberg.DecimalTypeOf(24,
2), iceberg.Decimal{
+ assertBounds(t, df.UpperBoundValues()[15],
iceberg.MustDecimalTypeOf(24, 2), iceberg.Decimal{
Val: decimal128.FromBigInt(expectedUpper),
Scale: 2,
})
@@ -1009,7 +1009,7 @@ func TestDecimalPhysicalTypes(t *testing.T) {
FieldID: 1,
Mode: internal.MetricsMode{Typ:
internal.MetricModeFull},
ColName: "value",
- IcebergTyp:
iceberg.DecimalTypeOf(tt.precision, tt.scale),
+ IcebergTyp:
iceberg.MustDecimalTypeOf(tt.precision, tt.scale),
},
}
@@ -1031,13 +1031,13 @@ func TestDecimalPhysicalTypes(t *testing.T) {
require.Contains(t, df.UpperBoundValues(), 1)
// Verify the actual values
- minLit, err :=
iceberg.LiteralFromBytes(iceberg.DecimalTypeOf(tt.precision, tt.scale),
df.LowerBoundValues()[1])
+ minLit, err :=
iceberg.LiteralFromBytes(iceberg.MustDecimalTypeOf(tt.precision, tt.scale),
df.LowerBoundValues()[1])
require.NoError(t, err)
minDec :=
minLit.(iceberg.TypedLiteral[iceberg.Decimal]).Value()
assert.Equal(t, uint64(tt.expectedMin),
minDec.Val.LowBits())
assert.Equal(t, tt.scale, minDec.Scale)
- maxLit, err :=
iceberg.LiteralFromBytes(iceberg.DecimalTypeOf(tt.precision, tt.scale),
df.UpperBoundValues()[1])
+ maxLit, err :=
iceberg.LiteralFromBytes(iceberg.MustDecimalTypeOf(tt.precision, tt.scale),
df.UpperBoundValues()[1])
require.NoError(t, err)
maxDec :=
maxLit.(iceberg.TypedLiteral[iceberg.Decimal]).Value()
assert.Equal(t, uint64(tt.expectedMax),
maxDec.Val.LowBits())
diff --git a/table/internal/utils_test.go b/table/internal/utils_test.go
index bb41dbe49..61ae2fd64 100644
--- a/table/internal/utils_test.go
+++ b/table/internal/utils_test.go
@@ -388,7 +388,7 @@ func
TestDataFileStatisticsDecimalPartitionManifestRoundTrip(t *testing.T) {
schema := iceberg.NewSchema(1, iceberg.NestedField{
ID: 1,
Name: "price",
- Type: iceberg.DecimalTypeOf(10, 2),
+ Type: iceberg.MustDecimalTypeOf(10, 2),
})
spec := iceberg.NewPartitionSpecID(1, iceberg.PartitionField{
SourceIDs: []int{1},
diff --git a/table/internal/variant_bounds.go b/table/internal/variant_bounds.go
index 21e74463c..f36d3cca0 100644
--- a/table/internal/variant_bounds.go
+++ b/table/internal/variant_bounds.go
@@ -136,7 +136,12 @@ func arrowLeafToIceberg(dt arrow.DataType)
(iceberg.PrimitiveType, bool) {
return iceberg.PrimitiveTypes.TimestampTzNs, true
}
case *arrow.Decimal128Type:
- return iceberg.DecimalTypeOf(int(t.Precision), int(t.Scale)),
true
+ dec, err := iceberg.DecimalTypeOf(int(t.Precision),
int(t.Scale))
+ if err != nil {
+ return nil, false
+ }
+
+ return dec, true
case arrow.ExtensionType:
if t.ExtensionName() == "arrow.uuid" {
return iceberg.PrimitiveTypes.UUID, true
diff --git a/table/internal/variant_bounds_test.go
b/table/internal/variant_bounds_test.go
index d7b5d008a..9a84577ae 100644
--- a/table/internal/variant_bounds_test.go
+++ b/table/internal/variant_bounds_test.go
@@ -532,3 +532,29 @@ func TestVariantBoundLiteralMalformed(t *testing.T) {
assert.False(t, ok, "malformed bytes yield no usable bound")
}
}
+
+func TestArrowLeafToIcebergRejectsInvalidDecimal(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ precision int32
+ scale int32
+ valid bool
+ }{
+ {"valid", 10, 2, true},
+ {"zero precision", 0, 0, false},
+ {"too large precision", 39, 0, false},
+ {"negative scale", 10, -1, false},
+ {"scale above precision", 5, 6, false},
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ typ, ok := arrowLeafToIceberg(&arrow.Decimal128Type{
+ Precision: tc.precision,
+ Scale: tc.scale,
+ })
+ assert.Equal(t, tc.valid, ok)
+ if !tc.valid {
+ assert.Nil(t, typ)
+ }
+ })
+ }
+}
diff --git a/table/metadata_internal_test.go b/table/metadata_internal_test.go
index 522dd0eb6..ae6206eba 100644
--- a/table/metadata_internal_test.go
+++ b/table/metadata_internal_test.go
@@ -2250,7 +2250,7 @@ func TestTableDataV2NoSnapshots(t *testing.T) {
"default-sort-order-id": 0
}`
schema := iceberg.NewSchema(1, iceberg.NestedField{
- Type: iceberg.FixedTypeOf(1),
+ Type: iceberg.MustFixedTypeOf(1),
ID: 1,
Name: "struct_name",
Required: true,
diff --git a/table/partition_residual_test.go b/table/partition_residual_test.go
index ed0f74708..84fd71f04 100644
--- a/table/partition_residual_test.go
+++ b/table/partition_residual_test.go
@@ -82,7 +82,7 @@ func
TestPartitionResidualEvaluatorElidesSatisfiedIdentityPredicate(t *testing.T
func TestPartitionResidualEvaluatorNormalizesDecodedLiteralValues(t
*testing.T) {
schema := iceberg.NewSchema(1, iceberg.NestedField{
- ID: 1, Name: "price", Type: iceberg.DecimalTypeOf(10, 2),
+ ID: 1, Name: "price", Type: iceberg.MustDecimalTypeOf(10, 2),
})
spec := iceberg.NewPartitionSpec(iceberg.PartitionField{
SourceIDs: []int{1}, FieldID: 1000, Name: "price", Transform:
iceberg.IdentityTransform{},
diff --git a/table/partitioned_fanout_writer_review_test.go
b/table/partitioned_fanout_writer_review_test.go
index 61c08a3d3..1a3ed000a 100644
--- a/table/partitioned_fanout_writer_review_test.go
+++ b/table/partitioned_fanout_writer_review_test.go
@@ -32,7 +32,7 @@ func (s *FanoutWriterTestSuite)
TestBinaryPartitionValuesDoNotAliasArrowStorage(
icebergType iceberg.Type
}{
{name: "binary", arrowType: arrow.BinaryTypes.Binary,
icebergType: iceberg.PrimitiveTypes.Binary},
- {name: "fixed", arrowType:
&arrow.FixedSizeBinaryType{ByteWidth: 4}, icebergType: iceberg.FixedTypeOf(4)},
+ {name: "fixed", arrowType:
&arrow.FixedSizeBinaryType{ByteWidth: 4}, icebergType:
iceberg.MustFixedTypeOf(4)},
}
for _, test := range tests {
@@ -170,7 +170,7 @@ func (s *FanoutWriterTestSuite)
TestFixedSizeBinaryPartitionReportsWidthMismatch
defer record.Release()
icebergSchema := iceberg.NewSchema(1, iceberg.NestedField{
- ID: 1, Name: "part", Type: iceberg.FixedTypeOf(3),
+ ID: 1, Name: "part", Type: iceberg.MustFixedTypeOf(3),
})
spec := iceberg.NewPartitionSpec(iceberg.PartitionField{
SourceIDs: []int{1}, FieldID: 1000, Name: "part", Transform:
iceberg.IdentityTransform{},
diff --git a/table/partitioned_fanout_writer_test.go
b/table/partitioned_fanout_writer_test.go
index 3ed322643..e70bc008a 100644
--- a/table/partitioned_fanout_writer_test.go
+++ b/table/partitioned_fanout_writer_test.go
@@ -315,7 +315,7 @@ func (s *FanoutWriterTestSuite)
TestBinaryPartitionValuesUseComparableKeys() {
icebergType iceberg.Type
}{
{name: "binary", arrowType: arrow.BinaryTypes.Binary,
icebergType: iceberg.PrimitiveTypes.Binary},
- {name: "fixed", arrowType:
&arrow.FixedSizeBinaryType{ByteWidth: 4}, icebergType: iceberg.FixedTypeOf(4)},
+ {name: "fixed", arrowType:
&arrow.FixedSizeBinaryType{ByteWidth: 4}, icebergType:
iceberg.MustFixedTypeOf(4)},
}
for _, test := range tests {
@@ -2038,13 +2038,13 @@ func (s *FanoutWriterTestSuite)
TestBoundPartitionTransformsMatchArrowValues() {
},
{
name: "bucket decimal",
- sourceType: iceberg.DecimalTypeOf(10, 2),
+ sourceType: iceberg.MustDecimalTypeOf(10, 2),
transform: iceberg.BucketTransform{NumBuckets: 16},
build: buildDecimal,
},
{
name: "truncate decimal",
- sourceType: iceberg.DecimalTypeOf(10, 2),
+ sourceType: iceberg.MustDecimalTypeOf(10, 2),
transform: iceberg.TruncateTransform{Width: 10},
build: buildDecimal,
},
@@ -2064,7 +2064,7 @@ func (s *FanoutWriterTestSuite)
TestBoundPartitionTransformsMatchArrowValues() {
},
{
name: "bucket fixed",
- sourceType: iceberg.FixedTypeOf(4),
+ sourceType: iceberg.MustFixedTypeOf(4),
transform: iceberg.BucketTransform{NumBuckets: 16},
build: func() arrow.Array {
builder :=
array.NewFixedSizeBinaryBuilder(s.mem, &arrow.FixedSizeBinaryType{ByteWidth: 4})
@@ -2126,7 +2126,7 @@ func (s *FanoutWriterTestSuite)
TestArrowDecimalValuesPreserveSign() {
}{
{
name: "decimal32",
- sourceType: iceberg.DecimalTypeOf(8, 2),
+ sourceType: iceberg.MustDecimalTypeOf(8, 2),
build: func() arrow.Array {
builder := array.NewDecimal32Builder(s.mem,
&arrow.Decimal32Type{Precision: 8, Scale: 2})
builder.Append(arrowdecimal.Decimal32(-1234))
@@ -2139,7 +2139,7 @@ func (s *FanoutWriterTestSuite)
TestArrowDecimalValuesPreserveSign() {
},
{
name: "decimal64",
- sourceType: iceberg.DecimalTypeOf(18, 2),
+ sourceType: iceberg.MustDecimalTypeOf(18, 2),
build: func() arrow.Array {
builder := array.NewDecimal64Builder(s.mem,
&arrow.Decimal64Type{Precision: 18, Scale: 2})
builder.Append(arrowdecimal.Decimal64(-1234))
@@ -2236,7 +2236,7 @@ func (s *FanoutWriterTestSuite) TestVoidTransform() {
func (s *FanoutWriterTestSuite)
TestPartitionedLogicalTypesRequireIntFieldIDCase() {
icebergSchema := iceberg.NewSchemaWithIdentifiers(1, []int{1},
iceberg.NestedField{ID: 1, Name: "id", Type:
iceberg.PrimitiveTypes.Int64, Required: true},
- iceberg.NestedField{ID: 2, Name: "decimal_col", Type:
iceberg.DecimalTypeOf(10, 6), Required: true},
+ iceberg.NestedField{ID: 2, Name: "decimal_col", Type:
iceberg.MustDecimalTypeOf(10, 6), Required: true},
iceberg.NestedField{ID: 3, Name: "time_col", Type:
iceberg.PrimitiveTypes.Time, Required: true},
iceberg.NestedField{ID: 4, Name: "timestamp_col", Type:
iceberg.PrimitiveTypes.Timestamp, Required: true},
iceberg.NestedField{ID: 5, Name: "timestamptz_col", Type:
iceberg.PrimitiveTypes.TimestampTz, Required: true},
diff --git a/table/scanner_internal_test.go b/table/scanner_internal_test.go
index 59467f3ed..441ac4888 100644
--- a/table/scanner_internal_test.go
+++ b/table/scanner_internal_test.go
@@ -2368,7 +2368,7 @@ func TestArrowScanFiltersMissingColumnInitialDefault(t
*testing.T) {
).
AddColumn(
[]string{"new_decimal"},
- iceberg.DecimalTypeOf(9, 2),
+ iceberg.MustDecimalTypeOf(9, 2),
"",
false,
iceberg.DecimalLiteral(decimalDefault),
diff --git a/table/substrait/substrait_decimal_internal_test.go
b/table/substrait/substrait_decimal_internal_test.go
index 50f70d961..ab7c2ce96 100644
--- a/table/substrait/substrait_decimal_internal_test.go
+++ b/table/substrait/substrait_decimal_internal_test.go
@@ -58,7 +58,7 @@ func TestToDecimalLiteralUsesBoundFieldPrecision(t
*testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
- fieldType := iceberg.DecimalTypeOf(tc.precision,
tc.scale)
+ fieldType := iceberg.MustDecimalTypeOf(tc.precision,
tc.scale)
lit := decimalLiteral16Bytes(tc.scale)
got := toDecimalLiteral(fieldType, lit)
@@ -118,7 +118,7 @@ func TestToDecimalLiteralRealisticValues(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
- fieldType := iceberg.DecimalTypeOf(18, tc.scale)
+ fieldType := iceberg.MustDecimalTypeOf(18, tc.scale)
lit := iceberg.DecimalLiteral{Val: tc.val, Scale:
tc.scale}
got := toDecimalLiteral(fieldType, lit)
diff --git a/table/substrait/substrait_test.go
b/table/substrait/substrait_test.go
index fffc39470..9d4f380ce 100644
--- a/table/substrait/substrait_test.go
+++ b/table/substrait/substrait_test.go
@@ -38,11 +38,11 @@ func TestRefTypes(t *testing.T) {
iceberg.NestedField{ID: 6, Name: "f", Type:
iceberg.PrimitiveTypes.Date},
iceberg.NestedField{ID: 7, Name: "g", Type:
iceberg.PrimitiveTypes.Time},
iceberg.NestedField{ID: 8, Name: "h", Type:
iceberg.PrimitiveTypes.Timestamp},
- iceberg.NestedField{ID: 9, Name: "i", Type:
iceberg.DecimalTypeOf(9, 2)},
+ iceberg.NestedField{ID: 9, Name: "i", Type:
iceberg.MustDecimalTypeOf(9, 2)},
iceberg.NestedField{ID: 10, Name: "j", Type:
iceberg.PrimitiveTypes.String},
iceberg.NestedField{ID: 11, Name: "k", Type:
iceberg.PrimitiveTypes.Binary},
iceberg.NestedField{ID: 12, Name: "l", Type:
iceberg.PrimitiveTypes.UUID},
- iceberg.NestedField{ID: 13, Name: "m", Type:
iceberg.FixedTypeOf(5)})
+ iceberg.NestedField{ID: 13, Name: "m", Type:
iceberg.MustFixedTypeOf(5)})
tests := []struct {
name string
diff --git a/table/table_test.go b/table/table_test.go
index dae8b35fd..35d370910 100644
--- a/table/table_test.go
+++ b/table/table_test.go
@@ -2537,10 +2537,10 @@ func tableSchema() *iceberg.Schema {
iceberg.NestedField{ID: 11, Name: "date", Type:
iceberg.PrimitiveTypes.Date},
iceberg.NestedField{ID: 12, Name: "uuid", Type:
iceberg.PrimitiveTypes.UUID},
iceberg.NestedField{ID: 13, Name: "binary", Type:
iceberg.PrimitiveTypes.Binary},
- iceberg.NestedField{ID: 14, Name: "fixed", Type:
iceberg.FixedTypeOf(16)},
- iceberg.NestedField{ID: 15, Name: "small_dec", Type:
iceberg.DecimalTypeOf(8, 2)},
- iceberg.NestedField{ID: 16, Name: "med_dec", Type:
iceberg.DecimalTypeOf(16, 2)},
- iceberg.NestedField{ID: 17, Name: "large_dec", Type:
iceberg.DecimalTypeOf(24, 2)},
+ iceberg.NestedField{ID: 14, Name: "fixed", Type:
iceberg.MustFixedTypeOf(16)},
+ iceberg.NestedField{ID: 15, Name: "small_dec", Type:
iceberg.MustDecimalTypeOf(8, 2)},
+ iceberg.NestedField{ID: 16, Name: "med_dec", Type:
iceberg.MustDecimalTypeOf(16, 2)},
+ iceberg.NestedField{ID: 17, Name: "large_dec", Type:
iceberg.MustDecimalTypeOf(24, 2)},
)
}
diff --git a/table/transaction_test.go b/table/transaction_test.go
index cf323caa1..e035171a5 100644
--- a/table/transaction_test.go
+++ b/table/transaction_test.go
@@ -191,10 +191,10 @@ func (s *SparkIntegrationTestSuite)
TestDifferentDataTypes() {
iceberg.NestedField{ID: 10, Name: "date", Type:
iceberg.PrimitiveTypes.Date},
iceberg.NestedField{ID: 11, Name: "uuid", Type:
iceberg.PrimitiveTypes.UUID},
iceberg.NestedField{ID: 12, Name: "binary", Type:
iceberg.PrimitiveTypes.Binary},
- iceberg.NestedField{ID: 13, Name: "fixed", Type:
iceberg.FixedTypeOf(16)},
- iceberg.NestedField{ID: 14, Name: "small_dec", Type:
iceberg.DecimalTypeOf(8, 2)},
- iceberg.NestedField{ID: 15, Name: "med_dec", Type:
iceberg.DecimalTypeOf(16, 2)},
- iceberg.NestedField{ID: 16, Name: "large_dec", Type:
iceberg.DecimalTypeOf(24, 2)},
+ iceberg.NestedField{ID: 13, Name: "fixed", Type:
iceberg.MustFixedTypeOf(16)},
+ iceberg.NestedField{ID: 14, Name: "small_dec", Type:
iceberg.MustDecimalTypeOf(8, 2)},
+ iceberg.NestedField{ID: 15, Name: "med_dec", Type:
iceberg.MustDecimalTypeOf(16, 2)},
+ iceberg.NestedField{ID: 16, Name: "large_dec", Type:
iceberg.MustDecimalTypeOf(24, 2)},
iceberg.NestedField{
ID: 17, Name: "list", Type: &iceberg.ListType{
ElementID: 18,
diff --git a/table/update_schema_test.go b/table/update_schema_test.go
index 3d46f97ea..6ad7ca53b 100644
--- a/table/update_schema_test.go
+++ b/table/update_schema_test.go
@@ -1833,10 +1833,10 @@ func TestUnionByNamePromoteFloatToDouble(t *testing.T) {
func TestUnionByNamePromoteDecimalPrecision(t *testing.T) {
current := iceberg.NewSchema(1,
- iceberg.NestedField{ID: 1, Name: "amount", Type:
iceberg.DecimalTypeOf(9, 2), Required: true},
+ iceberg.NestedField{ID: 1, Name: "amount", Type:
iceberg.MustDecimalTypeOf(9, 2), Required: true},
)
incoming := iceberg.NewSchema(1,
- iceberg.NestedField{ID: 1, Name: "amount", Type:
iceberg.DecimalTypeOf(18, 2), Required: true},
+ iceberg.NestedField{ID: 1, Name: "amount", Type:
iceberg.MustDecimalTypeOf(18, 2), Required: true},
)
applied, err := NewUpdateSchema(unionTxn(t, current), true,
false).UnionByNameWith(incoming).Apply()
@@ -1844,7 +1844,7 @@ func TestUnionByNamePromoteDecimalPrecision(t *testing.T)
{
amount, ok := applied.FindFieldByName("amount")
require.True(t, ok)
- assert.Equal(t, iceberg.DecimalTypeOf(18, 2), amount.Type)
+ assert.Equal(t, iceberg.MustDecimalTypeOf(18, 2), amount.Type)
}
func TestUnionByNameIgnoreNarrowingType(t *testing.T) {
@@ -2334,11 +2334,11 @@ func TestUnionByNameRejectsMistypedNativeDefault(t
*testing.T) {
func TestUnionByNamePromoteDecimalKeepsWiderWriteDefault(t *testing.T) {
current := iceberg.NewSchema(1,
- iceberg.NestedField{ID: 1, Name: "amount", Type:
iceberg.DecimalTypeOf(9, 2), Required: true},
+ iceberg.NestedField{ID: 1, Name: "amount", Type:
iceberg.MustDecimalTypeOf(9, 2), Required: true},
)
incoming := iceberg.NewSchema(1,
iceberg.NestedField{
- ID: 1, Name: "amount", Type: iceberg.DecimalTypeOf(18,
2), Required: true,
+ ID: 1, Name: "amount", Type:
iceberg.MustDecimalTypeOf(18, 2), Required: true,
WriteDefault: "123456789.12",
},
)
@@ -2348,7 +2348,7 @@ func
TestUnionByNamePromoteDecimalKeepsWiderWriteDefault(t *testing.T) {
amount, ok := applied.FindFieldByName("amount")
require.True(t, ok)
- assert.Equal(t, iceberg.DecimalTypeOf(18, 2), amount.Type)
+ assert.Equal(t, iceberg.MustDecimalTypeOf(18, 2), amount.Type)
assert.Equal(t, "123456789.12", amount.WriteDefault)
}
@@ -2553,8 +2553,8 @@ func TestUnionByNameRejectsInvalidPromotions(t
*testing.T) {
}{
{"string -> binary", iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary},
{"binary -> string", iceberg.PrimitiveTypes.Binary,
iceberg.PrimitiveTypes.String},
- {"fixed[16] -> uuid", iceberg.FixedTypeOf(16),
iceberg.PrimitiveTypes.UUID},
- {"decimal scale widening", iceberg.DecimalTypeOf(10, 1),
iceberg.DecimalTypeOf(10, 2)},
+ {"fixed[16] -> uuid", iceberg.MustFixedTypeOf(16),
iceberg.PrimitiveTypes.UUID},
+ {"decimal scale widening", iceberg.MustDecimalTypeOf(10, 1),
iceberg.MustDecimalTypeOf(10, 2)},
{"string -> int", iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Int32},
}
diff --git a/table/variant_residual_fastpath_test.go
b/table/variant_residual_fastpath_test.go
index 2ac4c3b49..74b7f265a 100644
--- a/table/variant_residual_fastpath_test.go
+++ b/table/variant_residual_fastpath_test.go
@@ -375,10 +375,10 @@ func TestFastPathDecimalScaleNearMissFallsBack(t
*testing.T) {
defer rec.Release()
iceSchema := iceberg.NewSchema(0, iceberg.NestedField{ID: 2, Name:
"payload", Type: iceberg.VariantType{}})
- term, err := iceberg.Extract("payload", "$.a",
iceberg.DecimalTypeOf(10, 4)).Bind(iceSchema, true)
+ term, err := iceberg.Extract("payload", "$.a",
iceberg.MustDecimalTypeOf(10, 4)).Bind(iceSchema, true)
require.NoError(t, err)
col := iceberg.VariantExtractColumn{Term: term.(iceberg.BoundExtract),
FieldID: 100, Name: "_x", SourcePath: []string{"payload"}}
- dt, err := TypeToArrowType(iceberg.DecimalTypeOf(10, 4), false, false)
+ dt, err := TypeToArrowType(iceberg.MustDecimalTypeOf(10, 4), false,
false)
require.NoError(t, err)
require.Nil(t, tryShreddedTypedColumn(varr, vpath(t, col.Term), dt,
mem), "scale near-miss must not fast-path")
diff --git a/table/variant_residual_test.go b/table/variant_residual_test.go
index 4ae5eea7f..72524bd10 100644
--- a/table/variant_residual_test.go
+++ b/table/variant_residual_test.go
@@ -49,12 +49,12 @@ func TestAppendExtractLiteral(t *testing.T) {
{"string", iceberg.PrimitiveTypes.String,
iceberg.NewLiteral("hi"), "hi"},
{"binary", iceberg.PrimitiveTypes.Binary,
iceberg.NewLiteral([]byte{1, 2}), []byte{1, 2}},
{"uuid", iceberg.PrimitiveTypes.UUID,
iceberg.NewLiteral(uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16}), uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}},
- {"fixed", iceberg.FixedTypeOf(16),
iceberg.NewLiteral(make([]byte, 16)), make([]byte, 16)},
+ {"fixed", iceberg.MustFixedTypeOf(16),
iceberg.NewLiteral(make([]byte, 16)), make([]byte, 16)},
{"date", iceberg.PrimitiveTypes.Date,
iceberg.NewLiteral(iceberg.Date(100)), arrow.Date32(100)},
{"time", iceberg.PrimitiveTypes.Time,
iceberg.NewLiteral(iceberg.Time(1_000_000)), arrow.Time64(1_000_000)},
{"timestamp micros", iceberg.PrimitiveTypes.Timestamp,
iceberg.NewLiteral(iceberg.Timestamp(123)), arrow.Timestamp(123)},
{"timestamp nanos", iceberg.PrimitiveTypes.TimestampNs,
iceberg.NewLiteral(iceberg.TimestampNano(123)), arrow.Timestamp(123)},
- {"decimal", iceberg.DecimalTypeOf(10, 2),
iceberg.NewLiteral(iceberg.Decimal{Val: decimal128.FromI64(1234), Scale: 2}),
decimal128.FromI64(1234)},
+ {"decimal", iceberg.MustDecimalTypeOf(10, 2),
iceberg.NewLiteral(iceberg.Decimal{Val: decimal128.FromI64(1234), Scale: 2}),
decimal128.FromI64(1234)},
} {
t.Run(tt.name, func(t *testing.T) {
dt, err := TypeToArrowType(tt.typ, false, false)
diff --git a/table/variant_shredded_write_test.go
b/table/variant_shredded_write_test.go
index d7157c527..4586f52f6 100644
--- a/table/variant_shredded_write_test.go
+++ b/table/variant_shredded_write_test.go
@@ -806,7 +806,7 @@ func TestShreddedVariantWriteRegularDecimalStats(t
*testing.T) {
mem := memory.DefaultAllocator
iceSchema := iceberg.NewSchema(0,
iceberg.NestedField{ID: 1, Name: "id", Type:
iceberg.PrimitiveTypes.Int64, Required: true},
- iceberg.NestedField{ID: 2, Name: "price", Type:
iceberg.DecimalTypeOf(9, 2)},
+ iceberg.NestedField{ID: 2, Name: "price", Type:
iceberg.MustDecimalTypeOf(9, 2)},
iceberg.NestedField{ID: 3, Name: "payload", Type:
iceberg.VariantType{}},
)
arrSchema, err := SchemaToArrowSchema(iceSchema, nil, true, false)
@@ -861,7 +861,7 @@ func TestShreddedVariantWriteRegularDecimalStats(t
*testing.T) {
// off and the regular decimal column keeps its default
FIXED_LEN_BYTE_ARRAY.
assert.Equal(t, parquet.Types.FixedLenByteArray, columnPhysicalType(t,
files[0].FilePath(), "price"))
- decTyp := iceberg.DecimalTypeOf(9, 2)
+ decTyp := iceberg.MustDecimalTypeOf(9, 2)
lb, err := iceberg.LiteralFromBytes(decTyp,
files[0].LowerBoundValues()[2])
require.NoError(t, err)
ub, err := iceberg.LiteralFromBytes(decTyp,
files[0].UpperBoundValues()[2])
@@ -878,7 +878,7 @@ func
TestShreddedVariantWriteRegularDecimalWithShreddedDecimal(t *testing.T) {
mem := memory.DefaultAllocator
iceSchema := iceberg.NewSchema(0,
iceberg.NestedField{ID: 1, Name: "id", Type:
iceberg.PrimitiveTypes.Int64, Required: true},
- iceberg.NestedField{ID: 2, Name: "price", Type:
iceberg.DecimalTypeOf(9, 2)},
+ iceberg.NestedField{ID: 2, Name: "price", Type:
iceberg.MustDecimalTypeOf(9, 2)},
iceberg.NestedField{ID: 3, Name: "payload", Type:
iceberg.VariantType{}},
)
arrSchema, err := SchemaToArrowSchema(iceSchema, nil, true, false)
@@ -936,7 +936,7 @@ func
TestShreddedVariantWriteRegularDecimalWithShreddedDecimal(t *testing.T) {
// Bounds are derived from the Arrow values, so they must be correct
regardless of
// the INT physical encoding.
- decTyp := iceberg.DecimalTypeOf(9, 2)
+ decTyp := iceberg.MustDecimalTypeOf(9, 2)
lb, err := iceberg.LiteralFromBytes(decTyp,
files[0].LowerBoundValues()[2])
require.NoError(t, err)
ub, err := iceberg.LiteralFromBytes(decTyp,
files[0].UpperBoundValues()[2])
diff --git a/transforms_decimal_bench_test.go b/transforms_decimal_bench_test.go
index 67c61b4f7..b41c3e36b 100644
--- a/transforms_decimal_bench_test.go
+++ b/transforms_decimal_bench_test.go
@@ -62,7 +62,7 @@ func BenchmarkBucketTransformDecimal(b *testing.B) {
})
b.Run("Transformer", func(b *testing.B) {
- transformer := transform.Transformer(iceberg.DecimalTypeOf(38,
0))
+ transformer :=
transform.Transformer(iceberg.MustDecimalTypeOf(38, 0))
b.ReportAllocs()
b.ResetTimer()
for i := range b.N {
@@ -112,7 +112,7 @@ func BenchmarkTruncateTransformDecimal(b *testing.B) {
}
})
b.Run(tt.name+"/Transformer", func(b *testing.B) {
- transformer, err :=
transform.Transformer(iceberg.DecimalTypeOf(38, 2))
+ transformer, err :=
transform.Transformer(iceberg.MustDecimalTypeOf(38, 2))
if err != nil {
b.Fatal(err)
}
diff --git a/transforms_test.go b/transforms_test.go
index 15c449131..2f27195ff 100644
--- a/transforms_test.go
+++ b/transforms_test.go
@@ -244,7 +244,7 @@ func TestToHumanStringValues(t *testing.T) {
{iceberg.VoidTransform{}, iceberg.PrimitiveTypes.String, nil,
"null"},
{iceberg.IdentityTransform{}, iceberg.PrimitiveTypes.String,
nil, "null"},
{iceberg.TruncateTransform{Width: 1},
iceberg.PrimitiveTypes.Binary, []byte{0x00, 0x01, 0x02, 0x03}, "AAECAw=="},
- {iceberg.TruncateTransform{Width: 1}, iceberg.DecimalTypeOf(9,
2), iceberg.Decimal{
+ {iceberg.TruncateTransform{Width: 1},
iceberg.MustDecimalTypeOf(9, 2), iceberg.Decimal{
Val: decVal, Scale: 2,
}, "14.21"},
{iceberg.TruncateTransform{Width: 1},
iceberg.PrimitiveTypes.Int32, int32(123), "123"},
@@ -258,7 +258,7 @@ func TestToHumanStringValues(t *testing.T) {
{iceberg.IdentityTransform{}, iceberg.PrimitiveTypes.Int64,
int64(-1234567890000), "-1234567890000"},
{iceberg.IdentityTransform{}, iceberg.PrimitiveTypes.String,
"a/b/c=d", "a/b/c=d"},
{iceberg.IdentityTransform{}, iceberg.PrimitiveTypes.Binary,
[]byte("foo"), "Zm9v"},
- {iceberg.IdentityTransform{}, iceberg.DecimalTypeOf(9, 2),
iceberg.Decimal{Val: negDecVal, Scale: 2}, "-1.50"},
+ {iceberg.IdentityTransform{}, iceberg.MustDecimalTypeOf(9, 2),
iceberg.Decimal{Val: negDecVal, Scale: 2}, "-1.50"},
}
for _, tt := range tests {
@@ -297,7 +297,7 @@ func TestToHumanString(t *testing.T) {
{"truncate_int32", iceberg.TruncateTransform{Width: 1},
iceberg.PrimitiveTypes.Int32, int32(123), "123"},
{"truncate_string", iceberg.TruncateTransform{Width: 1},
iceberg.PrimitiveTypes.String, "foo", "foo"},
{"truncate_bytes", iceberg.TruncateTransform{Width: 1},
iceberg.PrimitiveTypes.Binary, []byte{0x00, 0x01, 0x02, 0x03}, "AAECAw=="},
- {"truncate_decimal", iceberg.TruncateTransform{Width: 1},
iceberg.DecimalTypeOf(4, 2), iceberg.Decimal{Val: decVal, Scale: 2}, "14.21"},
+ {"truncate_decimal", iceberg.TruncateTransform{Width: 1},
iceberg.MustDecimalTypeOf(4, 2), iceberg.Decimal{Val: decVal, Scale: 2},
"14.21"},
{"truncate_nil", iceberg.TruncateTransform{Width: 1},
iceberg.PrimitiveTypes.String, nil, "null"},
{"void", iceberg.VoidTransform{},
iceberg.PrimitiveTypes.TimestampTz, tsMicros, "null"},
{"void_nil", iceberg.VoidTransform{},
iceberg.PrimitiveTypes.String, nil, "null"},
@@ -597,7 +597,7 @@ func TestCanTransform(t *testing.T) {
iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64, iceberg.PrimitiveTypes.Date,
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp, iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary, iceberg.PrimitiveTypes.UUID,
- iceberg.DecimalTypeOf(2, 1),
iceberg.FixedTypeOf(2),
+ iceberg.MustDecimalTypeOf(2, 1),
iceberg.MustFixedTypeOf(2),
},
notAllowed: []iceberg.Type{
&iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
@@ -614,7 +614,7 @@ func TestCanTransform(t *testing.T) {
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp, iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.TimestampNs,
iceberg.PrimitiveTypes.TimestampTzNs,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary, iceberg.PrimitiveTypes.UUID,
- iceberg.DecimalTypeOf(2, 1),
iceberg.FixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
+ iceberg.MustDecimalTypeOf(2, 1),
iceberg.MustFixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
iceberg.VariantType{},
iceberg.GeographyType{},
iceberg.GeometryType{},
@@ -627,7 +627,7 @@ func TestCanTransform(t *testing.T) {
iceberg.PrimitiveTypes.Int32,
iceberg.PrimitiveTypes.Int64, iceberg.PrimitiveTypes.Date,
iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.Timestamp, iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.TimestampNs,
iceberg.PrimitiveTypes.TimestampTzNs,
- iceberg.DecimalTypeOf(2, 1),
iceberg.PrimitiveTypes.String, iceberg.FixedTypeOf(2),
iceberg.PrimitiveTypes.Binary,
+ iceberg.MustDecimalTypeOf(2, 1),
iceberg.PrimitiveTypes.String, iceberg.MustFixedTypeOf(2),
iceberg.PrimitiveTypes.Binary,
iceberg.PrimitiveTypes.UUID,
},
notAllowed: []iceberg.Type{
@@ -642,12 +642,12 @@ func TestCanTransform(t *testing.T) {
transform: iceberg.TruncateTransform{},
allowed: []iceberg.Type{
iceberg.PrimitiveTypes.Int32,
iceberg.PrimitiveTypes.Int64, iceberg.PrimitiveTypes.String,
- iceberg.PrimitiveTypes.Binary,
iceberg.DecimalTypeOf(2, 1),
+ iceberg.PrimitiveTypes.Binary,
iceberg.MustDecimalTypeOf(2, 1),
},
notAllowed: []iceberg.Type{
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.Float32, iceberg.PrimitiveTypes.Float64,
iceberg.PrimitiveTypes.Date,
iceberg.PrimitiveTypes.Time, iceberg.PrimitiveTypes.Timestamp,
- iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.UUID, iceberg.FixedTypeOf(2),
+ iceberg.PrimitiveTypes.TimestampTz,
iceberg.PrimitiveTypes.UUID, iceberg.MustFixedTypeOf(2),
iceberg.PrimitiveTypes.TimestampNs,
iceberg.PrimitiveTypes.TimestampTzNs,
&iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
iceberg.VariantType{},
@@ -665,7 +665,7 @@ func TestCanTransform(t *testing.T) {
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.Int32, iceberg.PrimitiveTypes.Int64,
iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64, iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary, iceberg.PrimitiveTypes.UUID,
- iceberg.DecimalTypeOf(2, 1),
iceberg.FixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
+ iceberg.MustDecimalTypeOf(2, 1),
iceberg.MustFixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
iceberg.VariantType{},
iceberg.GeographyType{},
iceberg.GeometryType{},
@@ -681,7 +681,7 @@ func TestCanTransform(t *testing.T) {
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.Int32, iceberg.PrimitiveTypes.Int64,
iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64, iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary, iceberg.PrimitiveTypes.UUID,
- iceberg.DecimalTypeOf(2, 1),
iceberg.FixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
+ iceberg.MustDecimalTypeOf(2, 1),
iceberg.MustFixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
iceberg.VariantType{},
iceberg.GeographyType{},
iceberg.GeometryType{},
@@ -697,7 +697,7 @@ func TestCanTransform(t *testing.T) {
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.Int32, iceberg.PrimitiveTypes.Int64,
iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64, iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary, iceberg.PrimitiveTypes.UUID,
- iceberg.DecimalTypeOf(2, 1),
iceberg.FixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
+ iceberg.MustDecimalTypeOf(2, 1),
iceberg.MustFixedTypeOf(2), &iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
iceberg.VariantType{},
iceberg.GeographyType{},
iceberg.GeometryType{},
@@ -713,7 +713,7 @@ func TestCanTransform(t *testing.T) {
iceberg.PrimitiveTypes.Bool,
iceberg.PrimitiveTypes.Int32, iceberg.PrimitiveTypes.Int64,
iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64, iceberg.PrimitiveTypes.Time,
iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary, iceberg.PrimitiveTypes.UUID,
- iceberg.PrimitiveTypes.Date,
iceberg.DecimalTypeOf(2, 1), iceberg.FixedTypeOf(2),
+ iceberg.PrimitiveTypes.Date,
iceberg.MustDecimalTypeOf(2, 1), iceberg.MustFixedTypeOf(2),
&iceberg.StructType{}, &iceberg.ListType{},
&iceberg.MapType{},
iceberg.VariantType{},
iceberg.GeographyType{},
@@ -1198,7 +1198,7 @@ func TestTruncateTransformDecimal(t *testing.T) {
for _, width := range []int{1, 2, 3, 10, 50, 97, math.MaxInt32} {
transform := iceberg.TruncateTransform{Width: width}
for _, scale := range []int{0, 2, 9, 38} {
- transformer, err :=
transform.Transformer(iceberg.DecimalTypeOf(38, scale))
+ transformer, err :=
transform.Transformer(iceberg.MustDecimalTypeOf(38, scale))
require.NoError(t, err)
for _, value := range values {
t.Run(fmt.Sprintf("width=%d/scale=%d/value=%s",
width, scale, value), func(t *testing.T) {
@@ -1229,7 +1229,7 @@ func TestTruncateTransformDecimal(t *testing.T) {
t.Run("null", func(t *testing.T) {
transform := iceberg.TruncateTransform{Width: 50}
- transformer, err :=
transform.Transformer(iceberg.DecimalTypeOf(38, 2))
+ transformer, err :=
transform.Transformer(iceberg.MustDecimalTypeOf(38, 2))
require.NoError(t, err)
assert.Nil(t, transformer(nil))
assert.False(t,
transform.Apply(iceberg.Optional[iceberg.Literal]{Valid: false}).Valid)
diff --git a/types.go b/types.go
index 7407c1dba..adabde404 100644
--- a/types.go
+++ b/types.go
@@ -644,12 +644,24 @@ func validateFixedLength(length int) error {
return nil
}
-func FixedTypeOf(n int) FixedType {
+// FixedTypeOf returns the fixed type with the specified length.
+// It returns ErrInvalidArgument if the length is negative.
+func FixedTypeOf(n int) (FixedType, error) {
if err := validateFixedLength(n); err != nil {
- panic(fmt.Errorf("%w: %s", ErrInvalidArgument, err))
+ return FixedType{}, fmt.Errorf("%w: %w", ErrInvalidArgument,
err)
}
- return FixedType{len: n}
+ return FixedType{len: n}, nil
+}
+
+// MustFixedTypeOf is like FixedTypeOf but panics if the length is negative.
+func MustFixedTypeOf(n int) FixedType {
+ typ, err := FixedTypeOf(n)
+ if err != nil {
+ panic(err)
+ }
+
+ return typ
}
type FixedType struct {
@@ -669,12 +681,24 @@ func (f FixedType) Type() string { return
fmt.Sprintf("fixed[%d]", f.len) }
func (f FixedType) String() string { return fmt.Sprintf("fixed[%d]", f.len) }
func (f FixedType) primitive() {}
-func DecimalTypeOf(prec, scale int) DecimalType {
+// DecimalTypeOf returns the decimal type with the specified precision and
scale.
+// It returns ErrInvalidArgument if either value is outside the valid range.
+func DecimalTypeOf(prec, scale int) (DecimalType, error) {
if err := validateDecimalPrecisionScale(prec, scale); err != nil {
- panic(fmt.Errorf("%w: %w", ErrInvalidArgument, err))
+ return DecimalType{}, fmt.Errorf("%w: %w", ErrInvalidArgument,
err)
+ }
+
+ return DecimalType{precision: prec, scale: scale}, nil
+}
+
+// MustDecimalTypeOf is like DecimalTypeOf but panics for an invalid precision
or scale.
+func MustDecimalTypeOf(prec, scale int) DecimalType {
+ typ, err := DecimalTypeOf(prec, scale)
+ if err != nil {
+ panic(err)
}
- return DecimalType{precision: prec, scale: scale}
+ return typ
}
func validateDecimalPrecisionScale(precision, scale int) error {
diff --git a/types_test.go b/types_test.go
index eb752cfb2..eb3a453cd 100644
--- a/types_test.go
+++ b/types_test.go
@@ -47,10 +47,10 @@ func TestTypesBasic(t *testing.T) {
{"binary", iceberg.PrimitiveTypes.Binary},
{"unknown", iceberg.PrimitiveTypes.Unknown},
{"variant", iceberg.VariantType{}},
- {"fixed[0]", iceberg.FixedTypeOf(0)},
- {"fixed[5]", iceberg.FixedTypeOf(5)},
- {"decimal(9, 4)", iceberg.DecimalTypeOf(9, 4)},
- {"decimal(5, 5)", iceberg.DecimalTypeOf(5, 5)},
+ {"fixed[0]", iceberg.MustFixedTypeOf(0)},
+ {"fixed[5]", iceberg.MustFixedTypeOf(5)},
+ {"decimal(9, 4)", iceberg.MustDecimalTypeOf(9, 4)},
+ {"decimal(5, 5)", iceberg.MustDecimalTypeOf(5, 5)},
}
for _, tt := range tests {
@@ -74,12 +74,12 @@ func TestTypesBasic(t *testing.T) {
}
func TestFixedType(t *testing.T) {
- typ := iceberg.FixedTypeOf(5)
+ typ := iceberg.MustFixedTypeOf(5)
assert.Equal(t, 5, typ.Len())
assert.Equal(t, "fixed[5]", typ.String())
- assert.True(t, typ.Equals(iceberg.FixedTypeOf(5)))
- assert.False(t, typ.Equals(iceberg.FixedTypeOf(6)))
- assert.Equal(t, "fixed[0]", iceberg.FixedTypeOf(0).String())
+ assert.True(t, typ.Equals(iceberg.MustFixedTypeOf(5)))
+ assert.False(t, typ.Equals(iceberg.MustFixedTypeOf(6)))
+ assert.Equal(t, "fixed[0]", iceberg.MustFixedTypeOf(0).String())
t.Run("FixedTypeOf validates length", func(t *testing.T) {
assertFixedTypeOfPanicsWithInvalidArgument(t, -1)
@@ -129,30 +129,30 @@ func assertFixedTypeOfPanicsWithInvalidArgument(t
*testing.T, length int) {
assert.ErrorIs(t, err, iceberg.ErrInvalidArgument)
}()
- iceberg.FixedTypeOf(length)
+ iceberg.MustFixedTypeOf(length)
}
func TestDecimalType(t *testing.T) {
- typ := iceberg.DecimalTypeOf(9, 2)
+ typ := iceberg.MustDecimalTypeOf(9, 2)
assert.Equal(t, 9, typ.Precision())
assert.Equal(t, 2, typ.Scale())
assert.Equal(t, "decimal(9, 2)", typ.String())
- assert.True(t, typ.Equals(iceberg.DecimalTypeOf(9, 2)))
- assert.False(t, typ.Equals(iceberg.DecimalTypeOf(9, 3)))
+ assert.True(t, typ.Equals(iceberg.MustDecimalTypeOf(9, 2)))
+ assert.False(t, typ.Equals(iceberg.MustDecimalTypeOf(9, 3)))
t.Run("DecimalTypeOf validates precision and scale", func(t *testing.T)
{
assert.PanicsWithError(t, "invalid argument: invalid precision
0: must be greater than 0", func() {
- iceberg.DecimalTypeOf(0, 2)
+ iceberg.MustDecimalTypeOf(0, 2)
})
assert.PanicsWithError(t, "invalid argument: invalid precision
39: must be less than or equal to 38", func() {
- iceberg.DecimalTypeOf(39, 0)
+ iceberg.MustDecimalTypeOf(39, 0)
})
- assert.Equal(t, "decimal(10, 10)", iceberg.DecimalTypeOf(10,
10).String())
+ assert.Equal(t, "decimal(10, 10)",
iceberg.MustDecimalTypeOf(10, 10).String())
assert.PanicsWithError(t, "invalid argument: invalid scale -1:
must be greater than or equal to 0", func() {
- iceberg.DecimalTypeOf(10, -1)
+ iceberg.MustDecimalTypeOf(10, -1)
})
assert.PanicsWithError(t, "invalid argument: invalid scale 6:
must be less than or equal to precision 5", func() {
- iceberg.DecimalTypeOf(5, 6)
+ iceberg.MustDecimalTypeOf(5, 6)
})
})
}
@@ -197,10 +197,10 @@ func TestStructType(t *testing.T) {
typ := &iceberg.StructType{
FieldList: []iceberg.NestedField{
{ID: 1, Name: "required_field", Type:
iceberg.PrimitiveTypes.Int32, Required: true},
- {ID: 2, Name: "optional_field", Type:
iceberg.FixedTypeOf(5), Required: false},
+ {ID: 2, Name: "optional_field", Type:
iceberg.MustFixedTypeOf(5), Required: false},
{ID: 3, Name: "required_field", Type:
&iceberg.StructType{
FieldList: []iceberg.NestedField{
- {ID: 4, Name: "optional_field", Type:
iceberg.DecimalTypeOf(8, 2), Required: false},
+ {ID: 4, Name: "optional_field", Type:
iceberg.MustDecimalTypeOf(8, 2), Required: false},
{ID: 5, Name: "required_field", Type:
iceberg.PrimitiveTypes.Int64, Required: false},
},
}, Required: false},
@@ -223,7 +223,7 @@ func TestListType(t *testing.T) {
ElementRequired: false,
Element: &iceberg.StructType{
FieldList: []iceberg.NestedField{
- {ID: 2, Name: "required_field", Type:
iceberg.DecimalTypeOf(8, 2), Required: true},
+ {ID: 2, Name: "required_field", Type:
iceberg.MustDecimalTypeOf(8, 2), Required: true},
{ID: 3, Name: "optional_field", Type:
iceberg.PrimitiveTypes.Int64, Required: false},
},
},
@@ -237,7 +237,7 @@ func TestListType(t *testing.T) {
ElementRequired: true,
Element: &iceberg.StructType{
FieldList: []iceberg.NestedField{
- {ID: 2, Name: "required_field", Type:
iceberg.DecimalTypeOf(8, 2), Required: true},
+ {ID: 2, Name: "required_field", Type:
iceberg.MustDecimalTypeOf(8, 2), Required: true},
},
},
}))
@@ -356,8 +356,8 @@ func TestTypeStrings(t *testing.T) {
{iceberg.PrimitiveTypes.Binary, "binary"},
{iceberg.PrimitiveTypes.Unknown, "unknown"},
{iceberg.VariantType{}, "variant"},
- {iceberg.FixedTypeOf(22), "fixed[22]"},
- {iceberg.DecimalTypeOf(19, 18), "decimal(19, 18)"},
+ {iceberg.MustFixedTypeOf(22), "fixed[22]"},
+ {iceberg.MustDecimalTypeOf(19, 18), "decimal(19, 18)"},
{&iceberg.StructType{
FieldList: []iceberg.NestedField{
{ID: 1, Name: "required_field", Type:
iceberg.PrimitiveTypes.String, Required: true, Doc: "this is a doc"},
@@ -745,7 +745,7 @@ func TestNestedFieldMarshalBinaryDefaultsAsHex(t
*testing.T) {
{
name: "fixed",
field: iceberg.NestedField{
- ID: 2, Name: "fixed", Type:
iceberg.FixedTypeOf(3),
+ ID: 2, Name: "fixed", Type:
iceberg.MustFixedTypeOf(3),
InitialDefault: iceberg.FixedLiteral{1, 2, 3},
},
expected:
`{"id":2,"name":"fixed","required":false,"initial-default":"010203","type":"fixed[3]"}`,
@@ -1123,15 +1123,15 @@ func TestPromoteType(t *testing.T) {
{"float to double", iceberg.PrimitiveTypes.Float32,
iceberg.PrimitiveTypes.Float64, iceberg.PrimitiveTypes.Float64, false},
{"string to binary", iceberg.PrimitiveTypes.String,
iceberg.PrimitiveTypes.Binary, iceberg.PrimitiveTypes.Binary, false},
{"binary to string", iceberg.PrimitiveTypes.Binary,
iceberg.PrimitiveTypes.String, iceberg.PrimitiveTypes.String, false},
- {"fixed[16] to uuid", iceberg.FixedTypeOf(16),
iceberg.PrimitiveTypes.UUID, iceberg.PrimitiveTypes.UUID, false},
+ {"fixed[16] to uuid", iceberg.MustFixedTypeOf(16),
iceberg.PrimitiveTypes.UUID, iceberg.PrimitiveTypes.UUID, false},
{"unknown to any", iceberg.PrimitiveTypes.Unknown,
iceberg.PrimitiveTypes.Int64, iceberg.PrimitiveTypes.Int64, false},
// Decimal: precision may widen, scale must stay the same.
- {"decimal widen precision", iceberg.DecimalTypeOf(9, 2),
iceberg.DecimalTypeOf(18, 2), iceberg.DecimalTypeOf(18, 2), false},
- {"decimal same", iceberg.DecimalTypeOf(9, 2),
iceberg.DecimalTypeOf(9, 2), iceberg.DecimalTypeOf(9, 2), false},
- {"decimal narrow precision", iceberg.DecimalTypeOf(18, 2),
iceberg.DecimalTypeOf(9, 2), nil, true},
- {"decimal increase scale", iceberg.DecimalTypeOf(9, 2),
iceberg.DecimalTypeOf(18, 4), nil, true},
- {"decimal decrease scale", iceberg.DecimalTypeOf(9, 4),
iceberg.DecimalTypeOf(18, 2), nil, true},
+ {"decimal widen precision", iceberg.MustDecimalTypeOf(9, 2),
iceberg.MustDecimalTypeOf(18, 2), iceberg.MustDecimalTypeOf(18, 2), false},
+ {"decimal same", iceberg.MustDecimalTypeOf(9, 2),
iceberg.MustDecimalTypeOf(9, 2), iceberg.MustDecimalTypeOf(9, 2), false},
+ {"decimal narrow precision", iceberg.MustDecimalTypeOf(18, 2),
iceberg.MustDecimalTypeOf(9, 2), nil, true},
+ {"decimal increase scale", iceberg.MustDecimalTypeOf(9, 2),
iceberg.MustDecimalTypeOf(18, 4), nil, true},
+ {"decimal decrease scale", iceberg.MustDecimalTypeOf(9, 4),
iceberg.MustDecimalTypeOf(18, 2), nil, true},
// Geo types never promote to or from binary; only identical
types pass.
{"geometry same", geom4326, geom4326, geom4326, false},
@@ -1144,7 +1144,7 @@ func TestPromoteType(t *testing.T) {
{"geography algorithm mismatch", geog, geogKarney, nil, true},
{"disallowed int to string", iceberg.PrimitiveTypes.Int32,
iceberg.PrimitiveTypes.String, nil, true},
- {"disallowed fixed[8] to uuid", iceberg.FixedTypeOf(8),
iceberg.PrimitiveTypes.UUID, nil, true},
+ {"disallowed fixed[8] to uuid", iceberg.MustFixedTypeOf(8),
iceberg.PrimitiveTypes.UUID, nil, true},
}
for _, tt := range tests {
@@ -1161,3 +1161,34 @@ func TestPromoteType(t *testing.T) {
})
}
}
+
+func TestFixedTypeOfReturnsError(t *testing.T) {
+ typ, err := iceberg.FixedTypeOf(16)
+ require.NoError(t, err)
+ assert.Equal(t, 16, typ.Len())
+
+ typ, err = iceberg.FixedTypeOf(-1)
+ require.ErrorIs(t, err, iceberg.ErrInvalidArgument)
+ assert.Equal(t, iceberg.FixedType{}, typ)
+}
+
+func TestDecimalTypeOfReturnsError(t *testing.T) {
+ typ, err := iceberg.DecimalTypeOf(10, 2)
+ require.NoError(t, err)
+ assert.Equal(t, 10, typ.Precision())
+ assert.Equal(t, 2, typ.Scale())
+
+ for _, tc := range []struct {
+ precision int
+ scale int
+ }{
+ {0, 0},
+ {39, 0},
+ {10, -1},
+ {5, 6},
+ } {
+ typ, err := iceberg.DecimalTypeOf(tc.precision, tc.scale)
+ require.ErrorIs(t, err, iceberg.ErrInvalidArgument)
+ assert.Equal(t, iceberg.DecimalType{}, typ)
+ }
+}
diff --git a/variant_cast_test.go b/variant_cast_test.go
index 739822855..285689a39 100644
--- a/variant_cast_test.go
+++ b/variant_cast_test.go
@@ -106,11 +106,11 @@ func TestCastVariantLiteral(t *testing.T) {
{"date exact", func(b *variant.Builder) error { return
b.AppendDate(arrow.Date32(100)) }, PrimitiveTypes.Date, Date(100)},
{"timestamp micros exact", func(b *variant.Builder) error {
return b.AppendTimestamp(arrow.Timestamp(123), true, false) },
PrimitiveTypes.Timestamp, Timestamp(123)},
{"uuid exact", func(b *variant.Builder) error { return
b.AppendUUID(testUUID) }, PrimitiveTypes.UUID, testUUID},
- {"decimal scale match", func(b *variant.Builder) error { return
b.AppendDecimal8(2, decimal.Decimal64(1234)) }, DecimalTypeOf(10, 2),
Decimal{Val: decimal128.FromI64(1234), Scale: 2}},
- {"decimal32 scale match", func(b *variant.Builder) error {
return b.AppendDecimal4(2, decimal.Decimal32(1234)) }, DecimalTypeOf(10, 2),
Decimal{Val: decimal128.FromI64(1234), Scale: 2}},
- {"decimal128 scale match", func(b *variant.Builder) error {
return b.AppendDecimal16(3, decimal128.FromI64(123456)) }, DecimalTypeOf(20,
3), Decimal{Val: decimal128.FromI64(123456), Scale: 3}},
- {"decimal32 scale mismatch", func(b *variant.Builder) error {
return b.AppendDecimal4(2, decimal.Decimal32(1234)) }, DecimalTypeOf(10, 3),
nil},
- {"decimal scale mismatch", func(b *variant.Builder) error {
return b.AppendDecimal8(2, decimal.Decimal64(1234)) }, DecimalTypeOf(10, 3),
nil},
+ {"decimal scale match", func(b *variant.Builder) error { return
b.AppendDecimal8(2, decimal.Decimal64(1234)) }, MustDecimalTypeOf(10, 2),
Decimal{Val: decimal128.FromI64(1234), Scale: 2}},
+ {"decimal32 scale match", func(b *variant.Builder) error {
return b.AppendDecimal4(2, decimal.Decimal32(1234)) }, MustDecimalTypeOf(10,
2), Decimal{Val: decimal128.FromI64(1234), Scale: 2}},
+ {"decimal128 scale match", func(b *variant.Builder) error {
return b.AppendDecimal16(3, decimal128.FromI64(123456)) },
MustDecimalTypeOf(20, 3), Decimal{Val: decimal128.FromI64(123456), Scale: 3}},
+ {"decimal32 scale mismatch", func(b *variant.Builder) error {
return b.AppendDecimal4(2, decimal.Decimal32(1234)) }, MustDecimalTypeOf(10,
3), nil},
+ {"decimal scale mismatch", func(b *variant.Builder) error {
return b.AppendDecimal8(2, decimal.Decimal64(1234)) }, MustDecimalTypeOf(10,
3), nil},
{"string not castable to int64", func(b *variant.Builder) error
{ return b.AppendString("hi") }, PrimitiveTypes.Int64, nil},
{"nanos floor to micros pre-epoch", func(b *variant.Builder)
error { return b.AppendTimestamp(arrow.Timestamp(-1500), false, false) },
PrimitiveTypes.Timestamp, Timestamp(-2)},
{"date to nanos overflows int64", func(b *variant.Builder)
error { return b.AppendDate(arrow.Date32(200_000)) },
PrimitiveTypes.TimestampNs, nil},
diff --git a/variant_extract_test.go b/variant_extract_test.go
index 6a137a1c8..5901aaede 100644
--- a/variant_extract_test.go
+++ b/variant_extract_test.go
@@ -175,7 +175,7 @@ func TestExtractBindAllTargetTypes(t *testing.T) {
PrimitiveTypes.Float32, PrimitiveTypes.Float64,
PrimitiveTypes.Date,
PrimitiveTypes.Time, PrimitiveTypes.Timestamp,
PrimitiveTypes.TimestampTz,
PrimitiveTypes.TimestampNs, PrimitiveTypes.TimestampTzNs,
PrimitiveTypes.String,
- PrimitiveTypes.Binary, PrimitiveTypes.UUID, FixedTypeOf(16),
DecimalTypeOf(10, 2),
+ PrimitiveTypes.Binary, PrimitiveTypes.UUID,
MustFixedTypeOf(16), MustDecimalTypeOf(10, 2),
} {
t.Run(typ.String(), func(t *testing.T) {
bound, err := Extract("payload", "$.a",
typ).Bind(schema, true)
diff --git a/visitors_test.go b/visitors_test.go
index 96a7992b8..ce5cb82ba 100644
--- a/visitors_test.go
+++ b/visitors_test.go
@@ -410,7 +410,7 @@ func TestTranslateColumnNamesMissingFieldInitialDefault(t
*testing.T) {
{
name: "matching fixed metadata default",
field: iceberg.NestedField{
- ID: 2, Name: "missing_col", Type:
iceberg.FixedTypeOf(3),
+ ID: 2, Name: "missing_col", Type:
iceberg.MustFixedTypeOf(3),
InitialDefault: "010203",
},
expr: iceberg.EqualTo(ref, []byte{1, 2, 3}),
@@ -428,7 +428,7 @@ func TestTranslateColumnNamesMissingFieldInitialDefault(t
*testing.T) {
{
name: "matching native byte default",
field: iceberg.NestedField{
- ID: 2, Name: "missing_col", Type:
iceberg.FixedTypeOf(3),
+ ID: 2, Name: "missing_col", Type:
iceberg.MustFixedTypeOf(3),
InitialDefault: []byte{1, 2, 3},
},
expr: iceberg.EqualTo(ref, []byte{1, 2, 3}),
@@ -482,7 +482,7 @@ func TestTranslateColumnNamesMissingFieldInitialDefault(t
*testing.T) {
{
name: "matching decimal metadata default",
field: iceberg.NestedField{
- ID: 2, Name: "missing_col", Type:
iceberg.DecimalTypeOf(9, 2),
+ ID: 2, Name: "missing_col", Type:
iceberg.MustDecimalTypeOf(9, 2),
InitialDefault: "12.34",
},
expr: iceberg.EqualTo(ref, "12.34"),
@@ -1093,11 +1093,11 @@ func TestEvaluatorCmpTypes(t *testing.T) {
iceberg.NestedField{ID: 6, Name: "f", Type:
iceberg.PrimitiveTypes.Date},
iceberg.NestedField{ID: 7, Name: "g", Type:
iceberg.PrimitiveTypes.Time},
iceberg.NestedField{ID: 8, Name: "h", Type:
iceberg.PrimitiveTypes.Timestamp},
- iceberg.NestedField{ID: 9, Name: "i", Type:
iceberg.DecimalTypeOf(9, 2)},
+ iceberg.NestedField{ID: 9, Name: "i", Type:
iceberg.MustDecimalTypeOf(9, 2)},
iceberg.NestedField{ID: 10, Name: "j", Type:
iceberg.PrimitiveTypes.String},
iceberg.NestedField{ID: 11, Name: "k", Type:
iceberg.PrimitiveTypes.Binary},
iceberg.NestedField{ID: 12, Name: "l", Type:
iceberg.PrimitiveTypes.UUID},
- iceberg.NestedField{ID: 13, Name: "m", Type:
iceberg.FixedTypeOf(5)},
+ iceberg.NestedField{ID: 13, Name: "m", Type:
iceberg.MustFixedTypeOf(5)},
iceberg.NestedField{ID: 14, Name: "n", Type:
iceberg.PrimitiveTypes.TimestampNs},
iceberg.NestedField{ID: 15, Name: "o", Type:
iceberg.PrimitiveTypes.TimestampTzNs})
diff --git a/website/src/releases.md b/website/src/releases.md
index 636056764..4364cda9a 100644
--- a/website/src/releases.md
+++ b/website/src/releases.md
@@ -42,6 +42,7 @@ Per-release notes (highlights, breaking changes,
contributors) are published on
### Unreleased compatibility notes
+- **Fixed and decimal constructors return errors.** `iceberg.FixedTypeOf` and
`iceberg.DecimalTypeOf` now return `(type, error)` instead of panicking for
invalid inputs. Use `MustFixedTypeOf` or `MustDecimalTypeOf` only for
known-valid values.
- **SQL UDF representations now use struct literals.** The
`udf.NewSQLRepresentation(dialect, sql)` function, available since v0.7.0, is
removed. Use `udf.SQLRepresentation{Dialect: "trino", SQL: "x + 1"}` instead.
Empty fields and duplicate dialects are checked during metadata validation;
serialized JSON is unchanged.
- **Filesystem adapter construction consolidated.** Replace
`io.FSPreProcName(fsys, fn)` with `io.FS(fsys, io.WithNamePreprocessor(fn))`.
Plain `io.FS(fsys)` remains supported.
- **Table purge is required on catalogs.** The `catalog.Catalog` interface now
embeds `catalog.PurgeableCatalog`; every custom catalog implementation must
provide `PurgeTable(ctx, identifier) error`. The narrow
`catalog.PurgeableTable` interface is renamed to `catalog.PurgeableCatalog`.
Built-in purge behavior is unchanged.