public void TestStructArray() { // The following can be improved with a Builder class for StructArray. List <Field> fields = new List <Field>(); Field.Builder fieldBuilder = new Field.Builder(); fields.Add(fieldBuilder.Name("Strings").DataType(StringType.Default).Nullable(true).Build()); fieldBuilder = new Field.Builder(); fields.Add(fieldBuilder.Name("Ints").DataType(Int32Type.Default).Nullable(true).Build()); StructType structType = new StructType(fields); StringArray.Builder stringBuilder = new StringArray.Builder(); StringArray stringArray = stringBuilder.Append("joe").AppendNull().AppendNull().Append("mark").Build(); Int32Array.Builder intBuilder = new Int32Array.Builder(); Int32Array intArray = intBuilder.Append(1).Append(2).AppendNull().Append(4).Build(); List <Array> arrays = new List <Array>(); arrays.Add(stringArray); arrays.Add(intArray); ArrowBuffer.BitmapBuilder nullBitmap = new ArrowBuffer.BitmapBuilder(); var nullBitmapBuffer = nullBitmap.Append(true).Append(true).Append(false).Append(true).Build(); StructArray structs = new StructArray(structType, 4, arrays, nullBitmapBuffer, 1); Assert.Equal(4, structs.Length); Assert.Equal(1, structs.NullCount); ArrayData[] childArrays = structs.Data.Children; // Data for StringArray and Int32Array Assert.Equal(2, childArrays.Length); for (int i = 0; i < childArrays.Length; i++) { ArrayData arrayData = childArrays[i]; Assert.Null(arrayData.Children); if (i == 0) { Assert.Equal(ArrowTypeId.String, arrayData.DataType.TypeId); Array array = new StringArray(arrayData); StringArray structStringArray = array as StringArray; Assert.NotNull(structStringArray); Assert.Equal(structs.Length, structStringArray.Length); Assert.Equal(stringArray.Length, structStringArray.Length); Assert.Equal(stringArray.NullCount, structStringArray.NullCount); for (int j = 0; j < stringArray.Length; j++) { Assert.Equal(stringArray.GetString(j), structStringArray.GetString(j)); } } if (i == 1) { Assert.Equal(ArrowTypeId.Int32, arrayData.DataType.TypeId); Array array = new Int32Array(arrayData); Int32Array structIntArray = array as Int32Array; Assert.NotNull(structIntArray); Assert.Equal(structs.Length, structIntArray.Length); Assert.Equal(intArray.Length, structIntArray.Length); Assert.Equal(intArray.NullCount, structIntArray.NullCount); for (int j = 0; j < intArray.Length; j++) { Assert.Equal(intArray.GetValue(j), structIntArray.GetValue(j)); } } } }
public static Func <int, T> GetGetter <T>(IArrowArray array) { if (array is null) { return(null); } // TODO: determine fastest way to read out a value from the array. if (typeof(T) == typeof(bool)) { var booleanArray = new BooleanArray(array.Data); return((Func <int, T>)(object) new Func <int, bool>( index => booleanArray.GetBoolean(index).GetValueOrDefault())); } if (typeof(T) == typeof(bool?)) { var booleanArray = new BooleanArray(array.Data); return((Func <int, T>)(object) new Func <int, bool?>(booleanArray.GetBoolean)); } if (typeof(T) == typeof(sbyte)) { var int8Array = new Int8Array(array.Data); return((Func <int, T>)(object) new Func <int, sbyte>( index => int8Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(sbyte?)) { var int8Array = new Int8Array(array.Data); return((Func <int, T>)(object) new Func <int, sbyte?>(int8Array.GetValue)); } if (typeof(T) == typeof(byte)) { var uint8Array = new UInt8Array(array.Data); return((Func <int, T>)(object) new Func <int, byte>( index => uint8Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(byte?)) { var uint8Array = new UInt8Array(array.Data); return((Func <int, T>)(object) new Func <int, byte?>(uint8Array.GetValue)); } if (typeof(T) == typeof(short)) { var int16Array = new Int16Array(array.Data); return((Func <int, T>)(object) new Func <int, short>( index => int16Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(short?)) { var int16Array = new Int16Array(array.Data); return((Func <int, T>)(object) new Func <int, short?>(int16Array.GetValue)); } if (typeof(T) == typeof(ushort)) { var uint16Array = new UInt16Array(array.Data); return((Func <int, T>)(object) new Func <int, ushort>( index => uint16Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(ushort?)) { var uint16Array = new UInt16Array(array.Data); return((Func <int, T>)(object) new Func <int, ushort?>(uint16Array.GetValue)); } if (typeof(T) == typeof(int)) { var int32Array = new Int32Array(array.Data); return((Func <int, T>)(object) new Func <int, int>( index => int32Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(int?)) { var int32Array = new Int32Array(array.Data); return((Func <int, T>)(object) new Func <int, int?>(int32Array.GetValue)); } if (typeof(T) == typeof(uint)) { var uint32Array = new UInt32Array(array.Data); return((Func <int, T>)(object) new Func <int, uint>( index => uint32Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(uint?)) { var uint32Array = new UInt32Array(array.Data); return((Func <int, T>)(object) new Func <int, uint?>(uint32Array.GetValue)); } if (typeof(T) == typeof(long)) { var int64Array = new Int64Array(array.Data); return((Func <int, T>)(object) new Func <int, long>( index => int64Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(long?)) { var int64Array = new Int64Array(array.Data); return((Func <int, T>)(object) new Func <int, long?>(int64Array.GetValue)); } if (typeof(T) == typeof(ulong)) { var uint64Array = new UInt64Array(array.Data); return((Func <int, T>)(object) new Func <int, ulong>( index => uint64Array.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(ulong?)) { var uint64Array = new UInt64Array(array.Data); return((Func <int, T>)(object) new Func <int, ulong?>(uint64Array.GetValue)); } if (typeof(T) == typeof(double)) { var doubleArray = new DoubleArray(array.Data); return((Func <int, T>)(object) new Func <int, double>( index => doubleArray.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(double?)) { var doubleArray = new DoubleArray(array.Data); return((Func <int, T>)(object) new Func <int, double?>(doubleArray.GetValue)); } if (typeof(T) == typeof(float)) { var floatArray = new FloatArray(array.Data); return((Func <int, T>)(object) new Func <int, float>( index => floatArray.GetValue(index).GetValueOrDefault())); } if (typeof(T) == typeof(float?)) { var floatArray = new FloatArray(array.Data); return((Func <int, T>)(object) new Func <int, float?>(floatArray.GetValue)); } if (typeof(T) == typeof(DateTime)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime>( index => date32Array.GetDate(index).GetValueOrDefault().DateTime)); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime>( index => date64Array.GetDate(index).GetValueOrDefault().DateTime)); } } if (typeof(T) == typeof(DateTime?)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime?>( index => date32Array.GetDate(index)?.DateTime)); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTime?>( index => date64Array.GetDate(index)?.DateTime)); } } if (typeof(T) == typeof(DateTimeOffset)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset>( index => date32Array.GetDate(index).GetValueOrDefault())); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset>( index => date64Array.GetDate(index).GetValueOrDefault())); } } if (typeof(T) == typeof(DateTimeOffset?)) { if (array.Data.DataType.TypeId == ArrowTypeId.Date32) { var date32Array = new Date32Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset?>( date32Array.GetDate)); } else if (array.Data.DataType.TypeId == ArrowTypeId.Date64) { var date64Array = new Date64Array(array.Data); return((Func <int, T>)(object) new Func <int, DateTimeOffset?>( date64Array.GetDate)); } } if (typeof(T) == typeof(TimeSpan)) { var timestampArray = new TimestampArray(array.Data); return((Func <int, T>)(object) new Func <int, TimeSpan>( index => timestampArray.GetTimestamp(index).GetValueOrDefault().TimeOfDay)); } if (typeof(T) == typeof(TimeSpan?)) { var timestampArray = new TimestampArray(array.Data); return((Func <int, T>)(object) new Func <int, TimeSpan?>( index => timestampArray.GetTimestamp(index)?.TimeOfDay)); } if (typeof(T) == typeof(byte[])) { var binaryArray = new BinaryArray(array.Data); return((Func <int, T>)(object) new Func <int, byte[]>( // TODO: how to avoid this allocation/copy? index => binaryArray.GetBytes(index).ToArray())); } if (typeof(T) == typeof(string)) { var stringArray = new StringArray(array.Data); return((Func <int, T>)(object) new Func <int, string>( index => stringArray.GetString(index))); } // It's something else we don't yet support. switch (array.Data.DataType.TypeId) { case ArrowTypeId.Decimal: case ArrowTypeId.Dictionary: case ArrowTypeId.FixedSizedBinary: case ArrowTypeId.HalfFloat: case ArrowTypeId.Interval: case ArrowTypeId.List: case ArrowTypeId.Map: case ArrowTypeId.Null: case ArrowTypeId.Struct: case ArrowTypeId.Time32: case ArrowTypeId.Time64: case ArrowTypeId.Union: default: // TODO: support additional types? throw new NotSupportedException( $"Not supported array type: {array.Data.DataType.TypeId}"); } }