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/arrow-go.git


The following commit(s) were added to refs/heads/main by this push:
     new d5dcde9b fix(arrow): compare LargeListType like ListType in TypeEqual 
(#1440)
d5dcde9b is described below

commit d5dcde9bb8cd36aae7a3b73e0152c24977ada9e0
Author: Ondřej Pavela <[email protected]>
AuthorDate: Mon Nov 2 21:23:47 2026 +0100

    fix(arrow): compare LargeListType like ListType in TypeEqual (#1440)
    
    ### Rationale for this change
    
    `arrow.TypeEqual` has a case for `*ListType` but none for
    `*LargeListType`, so large lists fall through to `reflect.DeepEqual`.
    That compares the element field's metadata even when `CheckMetadata` is
    not given, and it also tells `nil` metadata apart from empty metadata.
    Two large list types that print identically can therefore compare
    unequal, and `array.Concatenate` rejects their arrays with "arrays to be
    concatenated must be identically typed".
    
    We hit this while concatenating batches read with iceberg-go's
    `arrow.use_large_types` scan option: a column read from a Parquet file
    and the same column filled with nulls for a file that predates it end up
    with element fields whose metadata differs only in being `nil` or empty.
    
    ### What changes are included in this PR?
    
    A `*LargeListType` case in `TypeEqual`, identical to the `*ListType`
    one: compare the element types, compare element metadata only with
    `CheckMetadata`, and compare element nullability.
    
    `*LargeListViewType` also has no case and falls through to
    `reflect.DeepEqual`; this PR leaves it unchanged.
    
    ### Are these changes tested?
    
    Yes. `TestTypeEqual` gains list and large list cases for element
    metadata (`nil` vs. empty, differing values with and without
    `CheckMetadata`), element nullability, and list vs. large list. The
    large list metadata cases fail without the fix.
    
    ### Are there any user-facing changes?
    
    `TypeEqual` now reports large list types equal when they differ only in
    element field metadata and `CheckMetadata` is not set, as it already
    does for list types.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-authored-by: Claude Opus 5.5 <[email protected]>
---
 arrow/compare.go      |  8 ++++++++
 arrow/compare_test.go | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/arrow/compare.go b/arrow/compare.go
index 997d25ad..52397fcf 100644
--- a/arrow/compare.go
+++ b/arrow/compare.go
@@ -65,6 +65,14 @@ func TypeEqual(left, right DataType, opts 
...TypeEqualOption) bool {
                        return false
                }
                return l.elem.Nullable == right.(*ListType).elem.Nullable
+       case *LargeListType:
+               if !TypeEqual(l.Elem(), right.(*LargeListType).Elem(), opts...) 
{
+                       return false
+               }
+               if cfg.metadata && 
!l.elem.Metadata.Equal(right.(*LargeListType).elem.Metadata) {
+                       return false
+               }
+               return l.elem.Nullable == right.(*LargeListType).elem.Nullable
        case *FixedSizeListType:
                if !TypeEqual(l.Elem(), right.(*FixedSizeListType).Elem(), 
opts...) {
                        return false
diff --git a/arrow/compare_test.go b/arrow/compare_test.go
index c78eb457..65b625d5 100644
--- a/arrow/compare_test.go
+++ b/arrow/compare_test.go
@@ -333,6 +333,41 @@ func TestTypeEqual(t *testing.T) {
                        },
                        false, true,
                },
+               {
+                       ListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true}),
+                       ListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{})}),
+                       true, false,
+               },
+               {
+                       ListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{"k1": "v1"})}),
+                       ListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{"k1": "v2"})}),
+                       false, true,
+               },
+               {
+                       LargeListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true}),
+                       LargeListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{})}),
+                       true, false,
+               },
+               {
+                       LargeListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{"k1": "v1"})}),
+                       LargeListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{"k1": "v2"})}),
+                       true, false,
+               },
+               {
+                       LargeListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{"k1": "v1"})}),
+                       LargeListOfField(Field{Name: "item", Type: 
BinaryTypes.String, Nullable: true, Metadata: 
MetadataFrom(map[string]string{"k1": "v2"})}),
+                       false, true,
+               },
+               {
+                       LargeListOf(BinaryTypes.String),
+                       LargeListOfNonNullable(BinaryTypes.String),
+                       false, false,
+               },
+               {
+                       LargeListOf(BinaryTypes.String),
+                       ListOf(BinaryTypes.String),
+                       false, false,
+               },
                {
                        MapOf(BinaryTypes.String, PrimitiveTypes.Int32),
                        MapOf(BinaryTypes.String, PrimitiveTypes.Int32),

Reply via email to