From f58759df9996458ac89093ca158985f23f5345b6 Mon Sep 17 00:00:00 2001 From: Curt Hagenlocher Date: Thu, 16 Nov 2023 20:27:25 -0800 Subject: [PATCH 1/3] Implement common interface to StructArray and RecordBatch. --- csharp/src/Apache.Arrow/Arrays/StructArray.cs | 10 +++- .../Interfaces/IArrowStructArray.cs | 30 +++++++++++ .../Apache.Arrow/Interfaces/IStructType.cs | 28 ++++++++++ csharp/src/Apache.Arrow/RecordBatch.cs | 6 ++- csharp/src/Apache.Arrow/Schema.cs | 14 +++-- csharp/src/Apache.Arrow/Types/StructType.cs | 8 ++- .../test/Apache.Arrow.Tests/FieldComparer.cs | 10 ++++ .../test/Apache.Arrow.Tests/IStructTests.cs | 53 +++++++++++++++++++ 8 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs create mode 100644 csharp/src/Apache.Arrow/Interfaces/IStructType.cs create mode 100644 csharp/test/Apache.Arrow.Tests/IStructTests.cs diff --git a/csharp/src/Apache.Arrow/Arrays/StructArray.cs b/csharp/src/Apache.Arrow/Arrays/StructArray.cs index 31aea9b41139b..6892832edf333 100644 --- a/csharp/src/Apache.Arrow/Arrays/StructArray.cs +++ b/csharp/src/Apache.Arrow/Arrays/StructArray.cs @@ -20,7 +20,7 @@ namespace Apache.Arrow { - public class StructArray : Array + public class StructArray : Array, IArrowStructArray { private IReadOnlyList _fields; @@ -55,5 +55,13 @@ private IReadOnlyList InitializeFields() } return result; } + + IStructType IArrowStructArray.Schema => (StructType)Data.DataType; + + int IArrowStructArray.ColumnCount => _fields.Count; + + IArrowArray IArrowStructArray.Column(string columnName) => _fields[((StructType)Data.DataType).GetFieldIndex(columnName)]; + + IArrowArray IArrowStructArray.Column(int columnIndex) => _fields[columnIndex]; } } diff --git a/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs b/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs new file mode 100644 index 0000000000000..85d2bc863240f --- /dev/null +++ b/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; + +namespace Apache.Arrow +{ + public interface IArrowStructArray : IDisposable + { + IStructType Schema { get; } + int ColumnCount { get; } + int Length { get; } + int NullCount { get; } + + IArrowArray Column(string columnName); + IArrowArray Column(int columnIndex); + } +} diff --git a/csharp/src/Apache.Arrow/Interfaces/IStructType.cs b/csharp/src/Apache.Arrow/Interfaces/IStructType.cs new file mode 100644 index 0000000000000..440801436a3ab --- /dev/null +++ b/csharp/src/Apache.Arrow/Interfaces/IStructType.cs @@ -0,0 +1,28 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Collections.Generic; + +namespace Apache.Arrow +{ + public interface IStructType + { + int FieldCount { get; } + + Field GetFieldByIndex(int index); + Field GetFieldByName(string name); + int GetFieldIndex(string name, IEqualityComparer comparer); + } +} diff --git a/csharp/src/Apache.Arrow/RecordBatch.cs b/csharp/src/Apache.Arrow/RecordBatch.cs index 566c77830265e..d9ff5bd137653 100644 --- a/csharp/src/Apache.Arrow/RecordBatch.cs +++ b/csharp/src/Apache.Arrow/RecordBatch.cs @@ -22,7 +22,7 @@ namespace Apache.Arrow { - public partial class RecordBatch : IDisposable + public partial class RecordBatch : IArrowStructArray { public Schema Schema { get; } public int ColumnCount => _arrays.Count; @@ -95,5 +95,9 @@ public RecordBatch Clone(MemoryAllocator allocator = default) } public override string ToString() => $"{nameof(RecordBatch)}: {ColumnCount} columns by {Length} rows"; + + IStructType IArrowStructArray.Schema => this.Schema; + + int IArrowStructArray.NullCount => 0; } } diff --git a/csharp/src/Apache.Arrow/Schema.cs b/csharp/src/Apache.Arrow/Schema.cs index 608b967630079..a797dd9e4fb8f 100644 --- a/csharp/src/Apache.Arrow/Schema.cs +++ b/csharp/src/Apache.Arrow/Schema.cs @@ -20,7 +20,7 @@ namespace Apache.Arrow { - public partial class Schema + public partial class Schema : IStructType { [Obsolete("Use `FieldsList` or `FieldsLookup` instead")] public IReadOnlyDictionary Fields => _fieldsDictionary; @@ -71,11 +71,17 @@ internal Schema(List fieldsList, IReadOnlyDictionary meta public Field GetFieldByName(string name) => FieldsLookup[name].FirstOrDefault(); - public int GetFieldIndex(string name, StringComparer comparer = default) + public int GetFieldIndex(string name, StringComparer comparer) + { + IEqualityComparer equalityComparer = (IEqualityComparer)comparer; + return GetFieldIndex(name, equalityComparer); + } + + public int GetFieldIndex(string name, IEqualityComparer comparer = default) { comparer ??= StringComparer.CurrentCulture; - return _fieldsList.IndexOf(_fieldsList.First(x => comparer.Compare(x.Name, name) == 0)); + return _fieldsList.IndexOf(_fieldsList.First(x => comparer.Equals(x.Name, name))); } public Schema RemoveField(int fieldIndex) @@ -116,5 +122,7 @@ public Schema SetField(int fieldIndex, Field newField) } public override string ToString() => $"{nameof(Schema)}: Num fields={_fieldsList.Count}, Num metadata={Metadata?.Count ?? 0}"; + + int IStructType.FieldCount => _fieldsList.Count; } } diff --git a/csharp/src/Apache.Arrow/Types/StructType.cs b/csharp/src/Apache.Arrow/Types/StructType.cs index 79e83db165c1d..13c2921475d1c 100644 --- a/csharp/src/Apache.Arrow/Types/StructType.cs +++ b/csharp/src/Apache.Arrow/Types/StructType.cs @@ -19,7 +19,7 @@ namespace Apache.Arrow.Types { - public sealed class StructType : NestedType + public sealed class StructType : NestedType, IStructType { public override ArrowTypeId TypeId => ArrowTypeId.Struct; public override string Name => "struct"; @@ -27,6 +27,8 @@ public sealed class StructType : NestedType public StructType(IReadOnlyList fields) : base(fields) { } + public Field GetFieldByIndex(int index) => Fields[index]; + public Field GetFieldByName(string name, IEqualityComparer comparer = default) { @@ -57,5 +59,9 @@ public int GetFieldIndex(string name, } public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor); + + int IStructType.FieldCount => Fields.Count; + + Field IStructType.GetFieldByName(string name) => GetFieldByName(name); } } diff --git a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs b/csharp/test/Apache.Arrow.Tests/FieldComparer.cs index d7dcc398f2443..87601f7ed82ab 100644 --- a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs +++ b/csharp/test/Apache.Arrow.Tests/FieldComparer.cs @@ -40,5 +40,15 @@ public static void Compare(Field expected, Field actual) actual.DataType.Accept(new ArrayTypeComparer(expected.DataType)); } + + public static void Compare(IStructType expected, IStructType actual) + { + Assert.Equal(expected.FieldCount, actual.FieldCount); + + for (int i = 0; i < expected.FieldCount; i++) + { + Compare(expected.GetFieldByIndex(i), actual.GetFieldByIndex(i)); + } + } } } diff --git a/csharp/test/Apache.Arrow.Tests/IStructTests.cs b/csharp/test/Apache.Arrow.Tests/IStructTests.cs new file mode 100644 index 0000000000000..78d6f881dace8 --- /dev/null +++ b/csharp/test/Apache.Arrow.Tests/IStructTests.cs @@ -0,0 +1,53 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Apache.Arrow.Types; +using Xunit; + +namespace Apache.Arrow.Tests +{ + public class IStructTests + { + [Fact] + public void StructsAndRecordBatchesAreSimilar() + { + Field stringField = new Field("column1", StringType.Default, true); + StringArray.Builder stringBuilder = new StringArray.Builder(); + StringArray stringArray = stringBuilder.Append("joe").AppendNull().AppendNull().Append("mark").Build(); + + Field intField = new Field("column2", Int32Type.Default, true); + Int32Array.Builder intBuilder = new Int32Array.Builder(); + Int32Array intArray = intBuilder.Append(1).Append(2).AppendNull().Append(4).Build(); + + Schema schema = new Schema(new[] { stringField, intField }, null); + RecordBatch batch = new RecordBatch(schema, new IArrowArray[] { stringArray, intArray }, intArray.Length); + IArrowStructArray structArray1 = batch; + + StructType structType = new StructType(new[] { stringField, intField }); + StructArray structArray = new StructArray(structType, intArray.Length, new IArrowArray[] { stringArray, intArray }, ArrowBuffer.Empty); + IArrowStructArray structArray2 = structArray; + + FieldComparer.Compare(structArray1.Schema, structArray2.Schema); + Assert.Equal(structArray1.Length, structArray2.Length); + Assert.Equal(structArray1.ColumnCount, structArray2.ColumnCount); + Assert.Equal(structArray1.NullCount, structArray2.NullCount); + + for (int i = 0; i < structArray1.ColumnCount; i++) + { + ArrowReaderVerifier.CompareArrays(structArray1.Column(i), structArray2.Column(i)); + } + } + } +} From 112db347f58559f7d06995f3358234223025b986 Mon Sep 17 00:00:00 2001 From: Curt Hagenlocher Date: Fri, 17 Nov 2023 08:11:56 -0800 Subject: [PATCH 2/3] Added Visitor support for IStructType and IArrowStructArray. --- csharp/src/Apache.Arrow/Arrays/StructArray.cs | 19 ++++- .../Interfaces/IArrowStructArray.cs | 9 ++- csharp/src/Apache.Arrow/RecordBatch.cs | 30 +++++++- csharp/src/Apache.Arrow/Schema.cs | 20 ++++++ csharp/src/Apache.Arrow/Types/IArrowType.cs | 1 + .../{Interfaces => Types}/IStructType.cs | 4 +- csharp/src/Apache.Arrow/Types/StructType.cs | 16 ++++- .../test/Apache.Arrow.Tests/FieldComparer.cs | 1 + .../test/Apache.Arrow.Tests/IStructTests.cs | 69 +++++++++++++++++++ 9 files changed, 157 insertions(+), 12 deletions(-) rename csharp/src/Apache.Arrow/{Interfaces => Types}/IStructType.cs (93%) diff --git a/csharp/src/Apache.Arrow/Arrays/StructArray.cs b/csharp/src/Apache.Arrow/Arrays/StructArray.cs index 6892832edf333..a83f12e6e42b9 100644 --- a/csharp/src/Apache.Arrow/Arrays/StructArray.cs +++ b/csharp/src/Apache.Arrow/Arrays/StructArray.cs @@ -44,7 +44,21 @@ public StructArray(ArrayData data) data.EnsureDataType(ArrowTypeId.Struct); } - public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor); + public override void Accept(IArrowArrayVisitor visitor) + { + switch (visitor) + { + case IArrowArrayVisitor structArrayVisitor: + structArrayVisitor.Visit(this); + break; + case IArrowArrayVisitor arrowStructVisitor: + arrowStructVisitor.Visit(this); + break; + default: + visitor.Visit(this); + break; + } + } private IReadOnlyList InitializeFields() { @@ -60,7 +74,8 @@ private IReadOnlyList InitializeFields() int IArrowStructArray.ColumnCount => _fields.Count; - IArrowArray IArrowStructArray.Column(string columnName) => _fields[((StructType)Data.DataType).GetFieldIndex(columnName)]; + IArrowArray IArrowStructArray.Column(string columnName, IEqualityComparer comparer) => + _fields[((StructType)Data.DataType).GetFieldIndex(columnName, comparer)]; IArrowArray IArrowStructArray.Column(int columnIndex) => _fields[columnIndex]; } diff --git a/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs b/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs index 85d2bc863240f..5e1ea0de5f923 100644 --- a/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs +++ b/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs @@ -13,18 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; +using System.Collections.Generic; +using Apache.Arrow.Types; namespace Apache.Arrow { - public interface IArrowStructArray : IDisposable + public interface IArrowStructArray : IArrowArray { IStructType Schema { get; } int ColumnCount { get; } - int Length { get; } - int NullCount { get; } - IArrowArray Column(string columnName); + IArrowArray Column(string columnName, IEqualityComparer comparer = default); IArrowArray Column(int columnIndex); } } diff --git a/csharp/src/Apache.Arrow/RecordBatch.cs b/csharp/src/Apache.Arrow/RecordBatch.cs index d9ff5bd137653..aa88c855967f3 100644 --- a/csharp/src/Apache.Arrow/RecordBatch.cs +++ b/csharp/src/Apache.Arrow/RecordBatch.cs @@ -19,6 +19,7 @@ using System.Diagnostics; using System.Linq; using Apache.Arrow.Memory; +using Apache.Arrow.Types; namespace Apache.Arrow { @@ -41,7 +42,12 @@ public IArrowArray Column(int i) public IArrowArray Column(string columnName) { - int fieldIndex = Schema.GetFieldIndex(columnName); + return Column(columnName, null); + } + + public IArrowArray Column(string columnName, IEqualityComparer comparer) + { + int fieldIndex = Schema.GetFieldIndex(columnName, comparer); return _arrays[fieldIndex]; } @@ -94,10 +100,30 @@ public RecordBatch Clone(MemoryAllocator allocator = default) return new RecordBatch(Schema, arrays, Length); } + public void Accept(IArrowArrayVisitor visitor) + { + switch (visitor) + { + case IArrowArrayVisitor recordBatchVisitor: + recordBatchVisitor.Visit(this); + break; + case IArrowArrayVisitor arrowStructVisitor: + arrowStructVisitor.Visit(this); + break; + default: + visitor.Visit(this); + break; + } + } + public override string ToString() => $"{nameof(RecordBatch)}: {ColumnCount} columns by {Length} rows"; IStructType IArrowStructArray.Schema => this.Schema; + int IArrowArray.NullCount => 0; + int IArrowArray.Offset => 0; + ArrayData IArrowArray.Data => throw new NotSupportedException("Unable to get data for RecordBatch"); - int IArrowStructArray.NullCount => 0; + bool IArrowArray.IsNull(int index) => false; + bool IArrowArray.IsValid(int index) => true; } } diff --git a/csharp/src/Apache.Arrow/Schema.cs b/csharp/src/Apache.Arrow/Schema.cs index a797dd9e4fb8f..adf9a8d278e63 100644 --- a/csharp/src/Apache.Arrow/Schema.cs +++ b/csharp/src/Apache.Arrow/Schema.cs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Apache.Arrow.Types; using System; using System.Collections.Generic; using System.Diagnostics; @@ -121,8 +122,27 @@ public Schema SetField(int fieldIndex, Field newField) return new Schema(fields, Metadata); } + public void Accept(IArrowTypeVisitor visitor) + { + if (visitor is IArrowTypeVisitor schemaVisitor) + { + schemaVisitor.Visit(this); + } + else if (visitor is IArrowTypeVisitor interfaceVisitor) + { + interfaceVisitor.Visit(this); + } + else + { + visitor.Visit(this); + } + } + public override string ToString() => $"{nameof(Schema)}: Num fields={_fieldsList.Count}, Num metadata={Metadata?.Count ?? 0}"; int IStructType.FieldCount => _fieldsList.Count; + string IArrowType.Name => "RecordBatch"; + ArrowTypeId IArrowType.TypeId => ArrowTypeId.RecordBatch; + bool IArrowType.IsFixedWidth => false; } } diff --git a/csharp/src/Apache.Arrow/Types/IArrowType.cs b/csharp/src/Apache.Arrow/Types/IArrowType.cs index cdf423e56f7a8..5e107813be828 100644 --- a/csharp/src/Apache.Arrow/Types/IArrowType.cs +++ b/csharp/src/Apache.Arrow/Types/IArrowType.cs @@ -49,6 +49,7 @@ public enum ArrowTypeId Map, FixedSizeList, Duration, + RecordBatch, } public interface IArrowType diff --git a/csharp/src/Apache.Arrow/Interfaces/IStructType.cs b/csharp/src/Apache.Arrow/Types/IStructType.cs similarity index 93% rename from csharp/src/Apache.Arrow/Interfaces/IStructType.cs rename to csharp/src/Apache.Arrow/Types/IStructType.cs index 440801436a3ab..554689ad2108b 100644 --- a/csharp/src/Apache.Arrow/Interfaces/IStructType.cs +++ b/csharp/src/Apache.Arrow/Types/IStructType.cs @@ -15,9 +15,9 @@ using System.Collections.Generic; -namespace Apache.Arrow +namespace Apache.Arrow.Types { - public interface IStructType + public interface IStructType : IArrowType { int FieldCount { get; } diff --git a/csharp/src/Apache.Arrow/Types/StructType.cs b/csharp/src/Apache.Arrow/Types/StructType.cs index 13c2921475d1c..e61c17b86d6ab 100644 --- a/csharp/src/Apache.Arrow/Types/StructType.cs +++ b/csharp/src/Apache.Arrow/Types/StructType.cs @@ -58,7 +58,21 @@ public int GetFieldIndex(string name, return -1; } - public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor); + public override void Accept(IArrowTypeVisitor visitor) + { + if (visitor is IArrowTypeVisitor structTypeVisitor) + { + structTypeVisitor.Visit(this); + } + else if (visitor is IArrowTypeVisitor interfaceVisitor) + { + interfaceVisitor.Visit(this); + } + else + { + visitor.Visit(this); + } + } int IStructType.FieldCount => Fields.Count; diff --git a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs b/csharp/test/Apache.Arrow.Tests/FieldComparer.cs index 87601f7ed82ab..64cfdf77c0224 100644 --- a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs +++ b/csharp/test/Apache.Arrow.Tests/FieldComparer.cs @@ -14,6 +14,7 @@ // limitations under the License. using System.Linq; +using Apache.Arrow.Types; using Xunit; namespace Apache.Arrow.Tests diff --git a/csharp/test/Apache.Arrow.Tests/IStructTests.cs b/csharp/test/Apache.Arrow.Tests/IStructTests.cs index 78d6f881dace8..1e23e7bfd8b07 100644 --- a/csharp/test/Apache.Arrow.Tests/IStructTests.cs +++ b/csharp/test/Apache.Arrow.Tests/IStructTests.cs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System.Text; using Apache.Arrow.Types; using Xunit; @@ -49,5 +50,73 @@ public void StructsAndRecordBatchesAreSimilar() ArrowReaderVerifier.CompareArrays(structArray1.Column(i), structArray2.Column(i)); } } + + [Fact] + public void VisitStructAndBatch() + { + Field stringField = new Field("column1", StringType.Default, true); + StructType level1 = new StructType(new[] { stringField }); + Field level1Field = new Field("column2", level1, false); + StructType level2 = new StructType(new[] { level1Field }); + Field level2Field = new Field("column3", level2, true); + Schema schema = new Schema(new[] { level2Field }, null); + + var visitor1 = new TestTypeVisitor1(); + visitor1.Visit(schema); + Assert.Equal("111utf8", visitor1.stringBuilder.ToString()); + var visitor2 = new TestTypeVisitor2(); + visitor2.Visit(schema); + Assert.Equal("322utf8", visitor2.stringBuilder.ToString()); + + StringArray stringArray = new StringArray.Builder().Append("one").AppendNull().AppendNull().Append("four").Build(); + StructArray level1Array = new StructArray(level1, stringArray.Length, new[] { stringArray }, ArrowBuffer.Empty); + ArrowBuffer nulls = new ArrowBuffer.BitmapBuilder(stringArray.Length).Append(false).Append(false).Append(true).Append(false).Build(); + StructArray level2Array = new StructArray(level2, stringArray.Length, new[] { level1Array }, nulls); + RecordBatch batch = new RecordBatch(schema, new IArrowArray[] { level2Array }, stringArray.Length); + + + } + + private class TestTypeVisitor1 : IArrowTypeVisitor, IArrowTypeVisitor + { + public StringBuilder stringBuilder = new StringBuilder(); + + public void Visit(IArrowType type) { stringBuilder.Append(type.Name); } + public void Visit(IStructType type) { stringBuilder.Append('1'); VisitFields(type); } + + protected void VisitFields(IStructType type) + { + for (int i = 0; i < type.FieldCount; i++) { type.GetFieldByIndex(i).DataType.Accept(this); } + } + } + + private class TestTypeVisitor2 : TestTypeVisitor1, + IArrowTypeVisitor, + IArrowTypeVisitor + { + public void Visit(StructType type) { stringBuilder.Append('2'); VisitFields(type); } + public void Visit(Schema type) { stringBuilder.Append('3'); VisitFields(type); } + } + + private class TestArrayVisitor1 : IArrowArrayVisitor, IArrowArrayVisitor + { + public StringBuilder stringBuilder = new StringBuilder(); + + public void Visit(IArrowArray array) { stringBuilder.Append(array.Data.DataType.Name); } + public void Visit(IArrowStructArray array) { stringBuilder.Append('1'); VisitFields(array); } + + protected void VisitFields(IArrowStructArray array) + { + for (int i = 0; i < array.ColumnCount; i++) { array.Column(i).Accept(this); } + } + } + + private class TestArrayVisitor2 : TestArrayVisitor1, + IArrowArrayVisitor, + IArrowArrayVisitor + { + public void Visit(StructArray array) { stringBuilder.Append('2'); VisitFields(array); } + public void Visit(RecordBatch batch) { stringBuilder.Append('3'); VisitFields(batch); } + } } } From 6a82f7872f12d3599e2f419d17a7787b79dc9be0 Mon Sep 17 00:00:00 2001 From: Curt Hagenlocher Date: Fri, 17 Nov 2023 14:01:32 -0800 Subject: [PATCH 3/3] Renames for clarity --- csharp/src/Apache.Arrow/Arrays/StructArray.cs | 12 +++++------ .../{IArrowStructArray.cs => IArrowRecord.cs} | 4 ++-- csharp/src/Apache.Arrow/RecordBatch.cs | 6 +++--- csharp/src/Apache.Arrow/Schema.cs | 6 +++--- .../Types/{IStructType.cs => IRecordType.cs} | 2 +- csharp/src/Apache.Arrow/Types/StructType.cs | 8 ++++---- .../test/Apache.Arrow.Tests/FieldComparer.cs | 2 +- .../{IStructTests.cs => RecordTests.cs} | 20 +++++++++---------- 8 files changed, 30 insertions(+), 30 deletions(-) rename csharp/src/Apache.Arrow/Interfaces/{IArrowStructArray.cs => IArrowRecord.cs} (92%) rename csharp/src/Apache.Arrow/Types/{IStructType.cs => IRecordType.cs} (95%) rename csharp/test/Apache.Arrow.Tests/{IStructTests.cs => RecordTests.cs} (90%) diff --git a/csharp/src/Apache.Arrow/Arrays/StructArray.cs b/csharp/src/Apache.Arrow/Arrays/StructArray.cs index a83f12e6e42b9..11d40e6d4e886 100644 --- a/csharp/src/Apache.Arrow/Arrays/StructArray.cs +++ b/csharp/src/Apache.Arrow/Arrays/StructArray.cs @@ -20,7 +20,7 @@ namespace Apache.Arrow { - public class StructArray : Array, IArrowStructArray + public class StructArray : Array, IArrowRecord { private IReadOnlyList _fields; @@ -51,7 +51,7 @@ public override void Accept(IArrowArrayVisitor visitor) case IArrowArrayVisitor structArrayVisitor: structArrayVisitor.Visit(this); break; - case IArrowArrayVisitor arrowStructVisitor: + case IArrowArrayVisitor arrowStructVisitor: arrowStructVisitor.Visit(this); break; default: @@ -70,13 +70,13 @@ private IReadOnlyList InitializeFields() return result; } - IStructType IArrowStructArray.Schema => (StructType)Data.DataType; + IRecordType IArrowRecord.Schema => (StructType)Data.DataType; - int IArrowStructArray.ColumnCount => _fields.Count; + int IArrowRecord.ColumnCount => _fields.Count; - IArrowArray IArrowStructArray.Column(string columnName, IEqualityComparer comparer) => + IArrowArray IArrowRecord.Column(string columnName, IEqualityComparer comparer) => _fields[((StructType)Data.DataType).GetFieldIndex(columnName, comparer)]; - IArrowArray IArrowStructArray.Column(int columnIndex) => _fields[columnIndex]; + IArrowArray IArrowRecord.Column(int columnIndex) => _fields[columnIndex]; } } diff --git a/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs b/csharp/src/Apache.Arrow/Interfaces/IArrowRecord.cs similarity index 92% rename from csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs rename to csharp/src/Apache.Arrow/Interfaces/IArrowRecord.cs index 5e1ea0de5f923..126d214df2fed 100644 --- a/csharp/src/Apache.Arrow/Interfaces/IArrowStructArray.cs +++ b/csharp/src/Apache.Arrow/Interfaces/IArrowRecord.cs @@ -18,9 +18,9 @@ namespace Apache.Arrow { - public interface IArrowStructArray : IArrowArray + public interface IArrowRecord : IArrowArray { - IStructType Schema { get; } + IRecordType Schema { get; } int ColumnCount { get; } IArrowArray Column(string columnName, IEqualityComparer comparer = default); diff --git a/csharp/src/Apache.Arrow/RecordBatch.cs b/csharp/src/Apache.Arrow/RecordBatch.cs index aa88c855967f3..9cc81b1648ea8 100644 --- a/csharp/src/Apache.Arrow/RecordBatch.cs +++ b/csharp/src/Apache.Arrow/RecordBatch.cs @@ -23,7 +23,7 @@ namespace Apache.Arrow { - public partial class RecordBatch : IArrowStructArray + public partial class RecordBatch : IArrowRecord { public Schema Schema { get; } public int ColumnCount => _arrays.Count; @@ -107,7 +107,7 @@ public void Accept(IArrowArrayVisitor visitor) case IArrowArrayVisitor recordBatchVisitor: recordBatchVisitor.Visit(this); break; - case IArrowArrayVisitor arrowStructVisitor: + case IArrowArrayVisitor arrowStructVisitor: arrowStructVisitor.Visit(this); break; default: @@ -118,7 +118,7 @@ public void Accept(IArrowArrayVisitor visitor) public override string ToString() => $"{nameof(RecordBatch)}: {ColumnCount} columns by {Length} rows"; - IStructType IArrowStructArray.Schema => this.Schema; + IRecordType IArrowRecord.Schema => this.Schema; int IArrowArray.NullCount => 0; int IArrowArray.Offset => 0; ArrayData IArrowArray.Data => throw new NotSupportedException("Unable to get data for RecordBatch"); diff --git a/csharp/src/Apache.Arrow/Schema.cs b/csharp/src/Apache.Arrow/Schema.cs index adf9a8d278e63..4357e8b2ddd44 100644 --- a/csharp/src/Apache.Arrow/Schema.cs +++ b/csharp/src/Apache.Arrow/Schema.cs @@ -21,7 +21,7 @@ namespace Apache.Arrow { - public partial class Schema : IStructType + public partial class Schema : IRecordType { [Obsolete("Use `FieldsList` or `FieldsLookup` instead")] public IReadOnlyDictionary Fields => _fieldsDictionary; @@ -128,7 +128,7 @@ public void Accept(IArrowTypeVisitor visitor) { schemaVisitor.Visit(this); } - else if (visitor is IArrowTypeVisitor interfaceVisitor) + else if (visitor is IArrowTypeVisitor interfaceVisitor) { interfaceVisitor.Visit(this); } @@ -140,7 +140,7 @@ public void Accept(IArrowTypeVisitor visitor) public override string ToString() => $"{nameof(Schema)}: Num fields={_fieldsList.Count}, Num metadata={Metadata?.Count ?? 0}"; - int IStructType.FieldCount => _fieldsList.Count; + int IRecordType.FieldCount => _fieldsList.Count; string IArrowType.Name => "RecordBatch"; ArrowTypeId IArrowType.TypeId => ArrowTypeId.RecordBatch; bool IArrowType.IsFixedWidth => false; diff --git a/csharp/src/Apache.Arrow/Types/IStructType.cs b/csharp/src/Apache.Arrow/Types/IRecordType.cs similarity index 95% rename from csharp/src/Apache.Arrow/Types/IStructType.cs rename to csharp/src/Apache.Arrow/Types/IRecordType.cs index 554689ad2108b..510edad23c6d2 100644 --- a/csharp/src/Apache.Arrow/Types/IStructType.cs +++ b/csharp/src/Apache.Arrow/Types/IRecordType.cs @@ -17,7 +17,7 @@ namespace Apache.Arrow.Types { - public interface IStructType : IArrowType + public interface IRecordType : IArrowType { int FieldCount { get; } diff --git a/csharp/src/Apache.Arrow/Types/StructType.cs b/csharp/src/Apache.Arrow/Types/StructType.cs index e61c17b86d6ab..da2411d34e7bc 100644 --- a/csharp/src/Apache.Arrow/Types/StructType.cs +++ b/csharp/src/Apache.Arrow/Types/StructType.cs @@ -19,7 +19,7 @@ namespace Apache.Arrow.Types { - public sealed class StructType : NestedType, IStructType + public sealed class StructType : NestedType, IRecordType { public override ArrowTypeId TypeId => ArrowTypeId.Struct; public override string Name => "struct"; @@ -64,7 +64,7 @@ public override void Accept(IArrowTypeVisitor visitor) { structTypeVisitor.Visit(this); } - else if (visitor is IArrowTypeVisitor interfaceVisitor) + else if (visitor is IArrowTypeVisitor interfaceVisitor) { interfaceVisitor.Visit(this); } @@ -74,8 +74,8 @@ public override void Accept(IArrowTypeVisitor visitor) } } - int IStructType.FieldCount => Fields.Count; + int IRecordType.FieldCount => Fields.Count; - Field IStructType.GetFieldByName(string name) => GetFieldByName(name); + Field IRecordType.GetFieldByName(string name) => GetFieldByName(name); } } diff --git a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs b/csharp/test/Apache.Arrow.Tests/FieldComparer.cs index 64cfdf77c0224..06fd2abdd13ad 100644 --- a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs +++ b/csharp/test/Apache.Arrow.Tests/FieldComparer.cs @@ -42,7 +42,7 @@ public static void Compare(Field expected, Field actual) actual.DataType.Accept(new ArrayTypeComparer(expected.DataType)); } - public static void Compare(IStructType expected, IStructType actual) + public static void Compare(IRecordType expected, IRecordType actual) { Assert.Equal(expected.FieldCount, actual.FieldCount); diff --git a/csharp/test/Apache.Arrow.Tests/IStructTests.cs b/csharp/test/Apache.Arrow.Tests/RecordTests.cs similarity index 90% rename from csharp/test/Apache.Arrow.Tests/IStructTests.cs rename to csharp/test/Apache.Arrow.Tests/RecordTests.cs index 1e23e7bfd8b07..09b0d2c6655ba 100644 --- a/csharp/test/Apache.Arrow.Tests/IStructTests.cs +++ b/csharp/test/Apache.Arrow.Tests/RecordTests.cs @@ -19,10 +19,10 @@ namespace Apache.Arrow.Tests { - public class IStructTests + public class RecordTests { [Fact] - public void StructsAndRecordBatchesAreSimilar() + public void StructArraysAndRecordBatchesAreSimilar() { Field stringField = new Field("column1", StringType.Default, true); StringArray.Builder stringBuilder = new StringArray.Builder(); @@ -34,11 +34,11 @@ public void StructsAndRecordBatchesAreSimilar() Schema schema = new Schema(new[] { stringField, intField }, null); RecordBatch batch = new RecordBatch(schema, new IArrowArray[] { stringArray, intArray }, intArray.Length); - IArrowStructArray structArray1 = batch; + IArrowRecord structArray1 = batch; StructType structType = new StructType(new[] { stringField, intField }); StructArray structArray = new StructArray(structType, intArray.Length, new IArrowArray[] { stringArray, intArray }, ArrowBuffer.Empty); - IArrowStructArray structArray2 = structArray; + IArrowRecord structArray2 = structArray; FieldComparer.Compare(structArray1.Schema, structArray2.Schema); Assert.Equal(structArray1.Length, structArray2.Length); @@ -77,14 +77,14 @@ public void VisitStructAndBatch() } - private class TestTypeVisitor1 : IArrowTypeVisitor, IArrowTypeVisitor + private class TestTypeVisitor1 : IArrowTypeVisitor, IArrowTypeVisitor { public StringBuilder stringBuilder = new StringBuilder(); public void Visit(IArrowType type) { stringBuilder.Append(type.Name); } - public void Visit(IStructType type) { stringBuilder.Append('1'); VisitFields(type); } + public void Visit(IRecordType type) { stringBuilder.Append('1'); VisitFields(type); } - protected void VisitFields(IStructType type) + protected void VisitFields(IRecordType type) { for (int i = 0; i < type.FieldCount; i++) { type.GetFieldByIndex(i).DataType.Accept(this); } } @@ -98,14 +98,14 @@ private class TestTypeVisitor2 : TestTypeVisitor1, public void Visit(Schema type) { stringBuilder.Append('3'); VisitFields(type); } } - private class TestArrayVisitor1 : IArrowArrayVisitor, IArrowArrayVisitor + private class TestArrayVisitor1 : IArrowArrayVisitor, IArrowArrayVisitor { public StringBuilder stringBuilder = new StringBuilder(); public void Visit(IArrowArray array) { stringBuilder.Append(array.Data.DataType.Name); } - public void Visit(IArrowStructArray array) { stringBuilder.Append('1'); VisitFields(array); } + public void Visit(IArrowRecord array) { stringBuilder.Append('1'); VisitFields(array); } - protected void VisitFields(IArrowStructArray array) + protected void VisitFields(IArrowRecord array) { for (int i = 0; i < array.ColumnCount; i++) { array.Column(i).Accept(this); } }