You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ee...@apache.org on 2022/06/14 03:28:30 UTC
[arrow] branch master updated: ARROW-16660: [C#] Add support for Time32Array and Time64Array (#13279)
This is an automated email from the ASF dual-hosted git repository.
eerhardt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new 6a936c4ff5 ARROW-16660: [C#] Add support for Time32Array and Time64Array (#13279)
6a936c4ff5 is described below
commit 6a936c4ff5007045e86f65f1a6b6c3c955ad5103
Author: Rishabh Rana <32...@users.noreply.github.com>
AuthorDate: Tue Jun 14 08:58:22 2022 +0530
ARROW-16660: [C#] Add support for Time32Array and Time64Array (#13279)
Implemented support without using TImespan in C# as it cannot hold values that have the resolution in microseconds & nanoseconds as specified on the Jira.
Lead-authored-by: Rishabh Rana <ri...@gmail.com>
Co-authored-by: Eric Erhardt <er...@microsoft.com>
Co-authored-by: ranarish <ri...@squarepoint-capital.com>
Signed-off-by: Eric Erhardt <er...@microsoft.com>
---
.../Arrays/ArrowArrayBuilderFactory.cs | 6 +-
.../src/Apache.Arrow/Arrays/ArrowArrayFactory.cs | 6 +-
csharp/src/Apache.Arrow/Arrays/Time32Array.cs | 117 +++++++++++++++++++++
csharp/src/Apache.Arrow/Arrays/Time64Array.cs | 117 +++++++++++++++++++++
csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs | 4 +
csharp/src/Apache.Arrow/RecordBatch.Builder.cs | 8 ++
.../IntegrationCommand.cs | 20 +++-
.../test/Apache.Arrow.Tests/ArrayBuilderTests.cs | 70 ++++++++++++
csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs | 8 ++
.../test/Apache.Arrow.Tests/ArrowReaderVerifier.cs | 4 +
csharp/test/Apache.Arrow.Tests/TableTests.cs | 2 +-
csharp/test/Apache.Arrow.Tests/TestData.cs | 30 +++++-
dev/archery/archery/integration/datagen.py | 3 +-
docs/source/status.rst | 2 +-
14 files changed, 386 insertions(+), 11 deletions(-)
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrowArrayBuilderFactory.cs b/csharp/src/Apache.Arrow/Arrays/ArrowArrayBuilderFactory.cs
index e7360942f3..618ac0212e 100644
--- a/csharp/src/Apache.Arrow/Arrays/ArrowArrayBuilderFactory.cs
+++ b/csharp/src/Apache.Arrow/Arrays/ArrowArrayBuilderFactory.cs
@@ -56,6 +56,10 @@ namespace Apache.Arrow
return new Date64Array.Builder();
case ArrowTypeId.Date32:
return new Date32Array.Builder();
+ case ArrowTypeId.Time32:
+ return new Time32Array.Builder(dataType as Time32Type);
+ case ArrowTypeId.Time64:
+ return new Time64Array.Builder(dataType as Time64Type);
case ArrowTypeId.List:
return new ListArray.Builder(dataType as ListType);
case ArrowTypeId.Decimal128:
@@ -69,8 +73,6 @@ namespace Apache.Arrow
case ArrowTypeId.HalfFloat:
case ArrowTypeId.Interval:
case ArrowTypeId.Map:
- case ArrowTypeId.Time32:
- case ArrowTypeId.Time64:
default:
throw new NotSupportedException($"An ArrowArrayBuilder cannot be built for type {dataType.TypeId}.");
}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrowArrayFactory.cs b/csharp/src/Apache.Arrow/Arrays/ArrowArrayFactory.cs
index 2b74709e73..819540a46a 100644
--- a/csharp/src/Apache.Arrow/Arrays/ArrowArrayFactory.cs
+++ b/csharp/src/Apache.Arrow/Arrays/ArrowArrayFactory.cs
@@ -65,6 +65,10 @@ namespace Apache.Arrow
return new Date64Array(data);
case ArrowTypeId.Date32:
return new Date32Array(data);
+ case ArrowTypeId.Time32:
+ return new Time32Array(data);
+ case ArrowTypeId.Time64:
+ return new Time64Array(data);
case ArrowTypeId.Decimal128:
return new Decimal128Array(data);
case ArrowTypeId.Decimal256:
@@ -74,8 +78,6 @@ namespace Apache.Arrow
case ArrowTypeId.HalfFloat:
case ArrowTypeId.Interval:
case ArrowTypeId.Map:
- case ArrowTypeId.Time32:
- case ArrowTypeId.Time64:
default:
throw new NotSupportedException($"An ArrowArray cannot be built for type {data.DataType.TypeId}.");
}
diff --git a/csharp/src/Apache.Arrow/Arrays/Time32Array.cs b/csharp/src/Apache.Arrow/Arrays/Time32Array.cs
new file mode 100644
index 0000000000..bdaf64d556
--- /dev/null
+++ b/csharp/src/Apache.Arrow/Arrays/Time32Array.cs
@@ -0,0 +1,117 @@
+// Licensed to the Apache Software Foundation (ASF) under one or moreDate32Array
+// 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 System.IO;
+
+namespace Apache.Arrow
+{
+ /// <summary>
+ /// The <see cref="Time32Array"/> class holds an array of <see cref="Int32" />, where each value is
+ /// stored as the number of seconds/ milliseconds (depending on the Time32Type) since midnight.
+ /// </summary>
+ public class Time32Array : PrimitiveArray<int>
+ {
+ /// <summary>
+ /// The <see cref="Builder"/> class can be used to fluently build <see cref="Time32Array"/> objects.
+ /// </summary>
+ public class Builder : PrimitiveArrayBuilder<int, Time32Array, Builder>
+ {
+ protected override Time32Array Build(
+ ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
+ int length, int nullCount, int offset) =>
+ new Time32Array(DataType, valueBuffer, nullBitmapBuffer, length, nullCount, offset);
+
+ protected Time32Type DataType { get; }
+
+ public Builder()
+ : this(Time32Type.Default) { }
+
+ public Builder(TimeUnit unit)
+ : this(new Time32Type(unit)) { }
+
+ /// <summary>
+ /// Construct a new instance of the <see cref="Builder"/> class.
+ /// </summary>
+ public Builder(Time32Type type)
+ : base()
+ {
+ DataType = type;
+ }
+ }
+
+ public Time32Array(
+ Time32Type type,
+ ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
+ int length, int nullCount, int offset)
+ : this(new ArrayData(type, length, nullCount, offset,
+ new[] { nullBitmapBuffer, valueBuffer }))
+ { }
+
+ public Time32Array(ArrayData data)
+ : base(data)
+ {
+ data.EnsureDataType(ArrowTypeId.Time32);
+ }
+
+ public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
+
+ /// <summary>
+ /// Get the time at the specified index as seconds
+ /// </summary>
+ /// <param name="index">Index at which to get the time.</param>
+ /// <returns>Returns an <see cref="Int32" />, or <c>null</c> if there is no object at that index.
+ /// </returns>
+ public int? GetSeconds(int index)
+ {
+ int? value = GetValue(index);
+ if (value == null)
+ {
+ return null;
+ }
+
+ var unit = ((Time32Type) Data.DataType).Unit;
+ return unit switch
+ {
+ TimeUnit.Second => value,
+ TimeUnit.Millisecond => value / 1_000,
+ _ => throw new InvalidDataException($"Unsupported time unit for Time32Type: {unit}")
+ };
+ }
+
+ /// <summary>
+ /// Get the time at the specified index as milliseconds
+ /// </summary>
+ /// <param name="index">Index at which to get the time.</param>
+ /// <returns>Returns an <see cref="Int32" />, or <c>null</c> if there is no object at that index.
+ /// </returns>
+ public int? GetMilliSeconds(int index)
+ {
+ int? value = GetValue(index);
+ if (value == null)
+ {
+ return null;
+ }
+
+ var unit = ((Time32Type)Data.DataType).Unit;
+ return unit switch
+ {
+ TimeUnit.Second => value * 1_000,
+ TimeUnit.Millisecond => value,
+ _ => throw new InvalidDataException($"Unsupported time unit for Time32Type: {unit}")
+ };
+ }
+ }
+}
diff --git a/csharp/src/Apache.Arrow/Arrays/Time64Array.cs b/csharp/src/Apache.Arrow/Arrays/Time64Array.cs
new file mode 100644
index 0000000000..127db63a7e
--- /dev/null
+++ b/csharp/src/Apache.Arrow/Arrays/Time64Array.cs
@@ -0,0 +1,117 @@
+// Licensed to the Apache Software Foundation (ASF) under one or moreDate32Array
+// 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 System.IO;
+
+namespace Apache.Arrow
+{
+ /// <summary>
+ /// The <see cref="Time64Array"/> class holds an array of <see cref="Int64" />, where each value is
+ /// stored as the number of microseconds/nanoseconds (depending on the Time64Type) since midnight.
+ /// </summary>
+ public class Time64Array : PrimitiveArray<long>
+ {
+ /// <summary>
+ /// The <see cref="Builder"/> class can be used to fluently build <see cref="Time64Array"/> objects.
+ /// </summary>
+ public class Builder : PrimitiveArrayBuilder<long, Time64Array, Builder>
+ {
+ protected override Time64Array Build(
+ ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
+ int length, int nullCount, int offset) =>
+ new Time64Array(DataType, valueBuffer, nullBitmapBuffer, length, nullCount, offset);
+
+ protected Time64Type DataType { get; }
+
+ public Builder()
+ : this(Time64Type.Default) { }
+
+ public Builder(TimeUnit unit)
+ : this(new Time64Type(unit)) { }
+
+ /// <summary>
+ /// Construct a new instance of the <see cref="Builder"/> class.
+ /// </summary>
+ public Builder(Time64Type type)
+ : base()
+ {
+ DataType = type;
+ }
+ }
+
+ public Time64Array(
+ Time64Type type,
+ ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
+ int length, int nullCount, int offset)
+ : this(new ArrayData(type, length, nullCount, offset,
+ new[] { nullBitmapBuffer, valueBuffer }))
+ { }
+
+ public Time64Array(ArrayData data)
+ : base(data)
+ {
+ data.EnsureDataType(ArrowTypeId.Time64);
+ }
+
+ public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
+
+ /// <summary>
+ /// Get the time at the specified index as microseconds
+ /// </summary>
+ /// <param name="index">Index at which to get the time.</param>
+ /// <returns>Returns a <see cref="Int64" />, or <c>null</c> if there is no object at that index.
+ /// </returns>
+ public long? GetMicroSeconds(int index)
+ {
+ long? value = GetValue(index);
+ if (value == null)
+ {
+ return null;
+ }
+
+ var unit = ((Time64Type)Data.DataType).Unit;
+ return unit switch
+ {
+ TimeUnit.Microsecond => value,
+ TimeUnit.Nanosecond => value / 1_000,
+ _ => throw new InvalidDataException($"Unsupported time unit for Time64Type: {unit}")
+ };
+ }
+
+ /// <summary>
+ /// Get the time at the specified index as nanoseconds
+ /// </summary>
+ /// <param name="index">Index at which to get the time.</param>
+ /// <returns>Returns a <see cref="Int64" />, or <c>null</c> if there is no object at that index.
+ /// </returns>
+ public long? GetNanoSeconds(int index)
+ {
+ long? value = GetValue(index);
+ if (value == null)
+ {
+ return null;
+ }
+
+ var unit = ((Time64Type)Data.DataType).Unit;
+ return unit switch
+ {
+ TimeUnit.Microsecond => value * 1_000,
+ TimeUnit.Nanosecond => value,
+ _ => throw new InvalidDataException($"Unsupported time unit for Time64Type: {unit}")
+ };
+ }
+ }
+}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs b/csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs
index ec1ad31f3a..0ffc856961 100644
--- a/csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs
+++ b/csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs
@@ -44,6 +44,8 @@ namespace Apache.Arrow.Ipc
IArrowArrayVisitor<TimestampArray>,
IArrowArrayVisitor<Date32Array>,
IArrowArrayVisitor<Date64Array>,
+ IArrowArrayVisitor<Time32Array>,
+ IArrowArrayVisitor<Time64Array>,
IArrowArrayVisitor<ListArray>,
IArrowArrayVisitor<StringArray>,
IArrowArrayVisitor<BinaryArray>,
@@ -91,6 +93,8 @@ namespace Apache.Arrow.Ipc
public void Visit(BooleanArray array) => CreateBuffers(array);
public void Visit(Date32Array array) => CreateBuffers(array);
public void Visit(Date64Array array) => CreateBuffers(array);
+ public void Visit(Time32Array array) => CreateBuffers(array);
+ public void Visit(Time64Array array) => CreateBuffers(array);
public void Visit(ListArray array)
{
diff --git a/csharp/src/Apache.Arrow/RecordBatch.Builder.cs b/csharp/src/Apache.Arrow/RecordBatch.Builder.cs
index c50bf1ace4..b54c0fdfea 100644
--- a/csharp/src/Apache.Arrow/RecordBatch.Builder.cs
+++ b/csharp/src/Apache.Arrow/RecordBatch.Builder.cs
@@ -52,6 +52,14 @@ namespace Apache.Arrow
new Decimal256Array.Builder(type), action);
public Date32Array Date32(Action<Date32Array.Builder> action) => Build<Date32Array, Date32Array.Builder>(new Date32Array.Builder(), action);
public Date64Array Date64(Action<Date64Array.Builder> action) => Build<Date64Array, Date64Array.Builder>(new Date64Array.Builder(), action);
+ public Time32Array Time32(Action<Time32Array.Builder> action) => Build<Time32Array, Time32Array.Builder>(new Time32Array.Builder(), action);
+ public Time32Array Time32(Time32Type type, Action<Time32Array.Builder> action) =>
+ Build<Time32Array, Time32Array.Builder>(
+ new Time32Array.Builder(type), action);
+ public Time64Array Time64(Action<Time64Array.Builder> action) => Build<Time64Array, Time64Array.Builder>(new Time64Array.Builder(), action);
+ public Time64Array Time64(Time64Type type, Action<Time64Array.Builder> action) =>
+ Build<Time64Array, Time64Array.Builder>(
+ new Time64Array.Builder(type), action);
public BinaryArray Binary(Action<BinaryArray.Builder> action) => Build<BinaryArray, BinaryArray.Builder>(new BinaryArray.Builder(), action);
public StringArray String(Action<StringArray.Builder> action) => Build<StringArray, StringArray.Builder>(new StringArray.Builder(), action);
public TimestampArray Timestamp(Action<TimestampArray.Builder> action) => Build<TimestampArray, TimestampArray.Builder>(new TimestampArray.Builder(), action);
diff --git a/csharp/test/Apache.Arrow.IntegrationTest/IntegrationCommand.cs b/csharp/test/Apache.Arrow.IntegrationTest/IntegrationCommand.cs
index d456624199..cb5aa74f93 100644
--- a/csharp/test/Apache.Arrow.IntegrationTest/IntegrationCommand.cs
+++ b/csharp/test/Apache.Arrow.IntegrationTest/IntegrationCommand.cs
@@ -266,6 +266,8 @@ namespace Apache.Arrow.IntegrationTest
IArrowTypeVisitor<Decimal256Type>,
IArrowTypeVisitor<Date32Type>,
IArrowTypeVisitor<Date64Type>,
+ IArrowTypeVisitor<Time32Type>,
+ IArrowTypeVisitor<Time64Type>,
IArrowTypeVisitor<TimestampType>,
IArrowTypeVisitor<StringType>,
IArrowTypeVisitor<BinaryType>,
@@ -310,6 +312,8 @@ namespace Apache.Arrow.IntegrationTest
public void Visit(UInt64Type type) => GenerateLongArray<ulong, UInt64Array>((v, n, c, nc, o) => new UInt64Array(v, n, c, nc, o), s => ulong.Parse(s));
public void Visit(FloatType type) => GenerateArray<float, FloatArray>((v, n, c, nc, o) => new FloatArray(v, n, c, nc, o));
public void Visit(DoubleType type) => GenerateArray<double, DoubleArray>((v, n, c, nc, o) => new DoubleArray(v, n, c, nc, o));
+ public void Visit(Time32Type type) => GenerateArray<int, Time32Array>((v, n, c, nc, o) => new Time32Array(type, v, n, c, nc, o));
+ public void Visit(Time64Type type) => GenerateLongArray<long, Time64Array>((v, n, c, nc, o) => new Time64Array(type, v, n, c, nc, o), s => long.Parse(s));
public void Visit(Decimal128Type type)
{
@@ -393,7 +397,21 @@ namespace Apache.Arrow.IntegrationTest
public void Visit(TimestampType type)
{
- throw new NotImplementedException();
+ ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
+
+ ArrowBuffer.Builder<long> valueBuilder = new ArrowBuffer.Builder<long>(JsonFieldData.Count);
+ var json = JsonFieldData.Data.GetRawText();
+ string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
+
+ foreach (string value in values)
+ {
+ valueBuilder.Append(long.Parse(value));
+ }
+ ArrowBuffer valueBuffer = valueBuilder.Build();
+
+ Array = new TimestampArray(
+ type, valueBuffer, validityBuffer,
+ JsonFieldData.Count, nullCount, 0);
}
public void Visit(StringType type)
diff --git a/csharp/test/Apache.Arrow.Tests/ArrayBuilderTests.cs b/csharp/test/Apache.Arrow.Tests/ArrayBuilderTests.cs
index 0b0754c506..0c58617ad1 100644
--- a/csharp/test/Apache.Arrow.Tests/ArrayBuilderTests.cs
+++ b/csharp/test/Apache.Arrow.Tests/ArrayBuilderTests.cs
@@ -38,6 +38,8 @@ namespace Apache.Arrow.Tests
TestArrayBuilder<UInt64Array, UInt64Array.Builder>(x => x.Append(10).Append(20).Append(30));
TestArrayBuilder<FloatArray, FloatArray.Builder>(x => x.Append(10).Append(20).Append(30));
TestArrayBuilder<DoubleArray, DoubleArray.Builder>(x => x.Append(10).Append(20).Append(30));
+ TestArrayBuilder<Time32Array, Time32Array.Builder>(x => x.Append(10).Append(20).Append(30));
+ TestArrayBuilder<Time64Array, Time64Array.Builder>(x => x.Append(10).Append(20).Append(30));
}
[Fact]
@@ -54,6 +56,8 @@ namespace Apache.Arrow.Tests
TestArrayBuilder<UInt64Array, UInt64Array.Builder>(x => x.Append(123).AppendNull().AppendNull().Append(456), 4, 2, 0x09);
TestArrayBuilder<FloatArray, FloatArray.Builder>(x => x.Append(123).AppendNull().AppendNull().Append(456), 4, 2, 0x09);
TestArrayBuilder<DoubleArray, DoubleArray.Builder>(x => x.Append(123).AppendNull().AppendNull().Append(456), 4, 2, 0x09);
+ TestArrayBuilder<Time32Array, Time32Array.Builder>(x => x.Append(123).AppendNull().AppendNull().Append(456), 4, 2, 0x09);
+ TestArrayBuilder<Time64Array, Time64Array.Builder>(x => x.Append(123).AppendNull().AppendNull().Append(456), 4, 2, 0x09);
}
[Fact]
@@ -221,6 +225,72 @@ namespace Apache.Arrow.Tests
}
}
+ public class Time32ArrayBuilder
+ {
+ [Fact]
+ public void ProducesExpectedArray()
+ {
+ var time32Type = new Time32Type(TimeUnit.Second);
+ var array = new Time32Array.Builder(time32Type)
+ .Append(1)
+ .Build();
+
+ Assert.Equal(1, array.Length);
+ var valueSeconds = array.GetSeconds(0);
+ Assert.NotNull(valueSeconds);
+ Assert.Equal(1, valueSeconds.Value);
+ var valueMilliSeconds = array.GetMilliSeconds(0);
+ Assert.NotNull(valueMilliSeconds);
+ Assert.Equal(1_000, valueMilliSeconds.Value);
+
+ time32Type = new Time32Type(TimeUnit.Millisecond);
+ array = new Time32Array.Builder(time32Type)
+ .Append(1_000)
+ .Build();
+
+ Assert.Equal(1, array.Length);
+ valueSeconds = array.GetSeconds(0);
+ Assert.NotNull(valueSeconds);
+ Assert.Equal(1, valueSeconds.Value);
+ valueMilliSeconds = array.GetMilliSeconds(0);
+ Assert.NotNull(valueMilliSeconds);
+ Assert.Equal(1_000, valueMilliSeconds.Value);
+ }
+ }
+
+ public class Time64ArrayBuilder
+ {
+ [Fact]
+ public void ProducesExpectedArray()
+ {
+ var time64Type = new Time64Type(TimeUnit.Microsecond);
+ var array = new Time64Array.Builder(time64Type)
+ .Append(1_000_000)
+ .Build();
+
+ Assert.Equal(1, array.Length);
+ var valueMicroSeconds = array.GetMicroSeconds(0);
+ Assert.NotNull(valueMicroSeconds);
+ Assert.Equal(1_000_000, valueMicroSeconds.Value);
+ var valueNanoSeconds = array.GetNanoSeconds(0);
+ Assert.NotNull(valueNanoSeconds);
+ Assert.Equal(1_000_000_000, valueNanoSeconds.Value);
+
+ time64Type = new Time64Type(TimeUnit.Nanosecond);
+ array = new Time64Array.Builder(time64Type)
+ .Append(1_000_000_000)
+ .Build();
+
+ Assert.Equal(1, array.Length);
+ valueMicroSeconds = array.GetMicroSeconds(0);
+ Assert.NotNull(valueMicroSeconds);
+ Assert.Equal(1_000_000, valueMicroSeconds.Value);
+ valueNanoSeconds = array.GetNanoSeconds(0);
+ Assert.NotNull(valueNanoSeconds);
+ Assert.Equal(1_000_000_000, valueNanoSeconds.Value);
+ }
+ }
+
private static TArray TestArrayBuilder<TArray, TArrayBuilder>(Action<TArrayBuilder> action, int expectedLength = 3, int expectedNullCount = 0, int expectedNulls = 0)
where TArray : IArrowArray
where TArrayBuilder : IArrowArrayBuilder<TArray>, new()
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs
index 18d405613b..1e3d4b12f5 100644
--- a/csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs
+++ b/csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs
@@ -107,6 +107,8 @@ namespace Apache.Arrow.Tests
TestSlice<DoubleArray, DoubleArray.Builder>(x => x.Append(10).Append(20).Append(30));
TestSlice<Date32Array, Date32Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).Append(new DateTime(2019, 1, 3)));
TestSlice<Date64Array, Date64Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).Append(new DateTime(2019, 1, 3)));
+ TestSlice<Time32Array, Time32Array.Builder>(x => x.Append(10).Append(20).Append(30));
+ TestSlice<Time64Array, Time64Array.Builder>(x => x.Append(10).Append(20).Append(30));
TestSlice<StringArray, StringArray.Builder>(x => x.Append("10").Append("20").Append("30"));
}
@@ -125,6 +127,8 @@ namespace Apache.Arrow.Tests
TestSlice<DoubleArray, DoubleArray.Builder>(x => x.Append(10).Append(20).AppendNull().Append(30));
TestSlice<Date32Array, Date32Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).AppendNull().Append(new DateTime(2019, 1, 3)));
TestSlice<Date64Array, Date64Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).AppendNull().Append(new DateTime(2019, 1, 3)));
+ TestSlice<Time32Array, Time32Array.Builder>(x => x.Append(10).AppendNull().Append(30));
+ TestSlice<Time64Array, Time64Array.Builder>(x => x.Append(10).AppendNull().Append(30));
}
[Fact]
@@ -177,6 +181,8 @@ namespace Apache.Arrow.Tests
IArrowArrayVisitor<UInt64Array>,
IArrowArrayVisitor<Date32Array>,
IArrowArrayVisitor<Date64Array>,
+ IArrowArrayVisitor<Time32Array>,
+ IArrowArrayVisitor<Time64Array>,
IArrowArrayVisitor<FloatArray>,
IArrowArrayVisitor<DoubleArray>,
IArrowArrayVisitor<BooleanArray>,
@@ -215,6 +221,8 @@ namespace Apache.Arrow.Tests
Assert.Equal(baseArray.GetDateTimeOffset(array.Offset), array.GetDateTimeOffset(0));
}
+ public void Visit(Time32Array array) => ValidateArrays(array);
+ public void Visit(Time64Array array) => ValidateArrays(array);
public void Visit(FloatArray array) => ValidateArrays(array);
public void Visit(DoubleArray array) => ValidateArrays(array);
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs b/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs
index a2c9a9ef7a..4a15bc7117 100644
--- a/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs
+++ b/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs
@@ -80,6 +80,8 @@ namespace Apache.Arrow.Tests
IArrowArrayVisitor<TimestampArray>,
IArrowArrayVisitor<Date32Array>,
IArrowArrayVisitor<Date64Array>,
+ IArrowArrayVisitor<Time32Array>,
+ IArrowArrayVisitor<Time64Array>,
IArrowArrayVisitor<ListArray>,
IArrowArrayVisitor<StringArray>,
IArrowArrayVisitor<FixedSizeBinaryArray>,
@@ -114,6 +116,8 @@ namespace Apache.Arrow.Tests
public void Visit(TimestampArray array) => CompareArrays(array);
public void Visit(Date32Array array) => CompareArrays(array);
public void Visit(Date64Array array) => CompareArrays(array);
+ public void Visit(Time32Array array) => CompareArrays(array);
+ public void Visit(Time64Array array) => CompareArrays(array);
public void Visit(ListArray array) => CompareArrays(array);
public void Visit(FixedSizeBinaryArray array) => CompareArrays(array);
public void Visit(Decimal128Array array) => CompareArrays(array);
diff --git a/csharp/test/Apache.Arrow.Tests/TableTests.cs b/csharp/test/Apache.Arrow.Tests/TableTests.cs
index 3e1107c2a5..45a14cc256 100644
--- a/csharp/test/Apache.Arrow.Tests/TableTests.cs
+++ b/csharp/test/Apache.Arrow.Tests/TableTests.cs
@@ -60,7 +60,7 @@ namespace Apache.Arrow.Tests
Table table1 = Table.TableFromRecordBatches(recordBatch1.Schema, recordBatches);
Assert.Equal(20, table1.RowCount);
- Assert.Equal(21, table1.ColumnCount);
+ Assert.Equal(23, table1.ColumnCount);
FixedSizeBinaryType type = new FixedSizeBinaryType(17);
Field newField1 = new Field(type.Name, type, false);
diff --git a/csharp/test/Apache.Arrow.Tests/TestData.cs b/csharp/test/Apache.Arrow.Tests/TestData.cs
index 9b6d0cf8b0..1166f95f3d 100644
--- a/csharp/test/Apache.Arrow.Tests/TestData.cs
+++ b/csharp/test/Apache.Arrow.Tests/TestData.cs
@@ -47,6 +47,8 @@ namespace Apache.Arrow.Tests
builder.Field(CreateField(DoubleType.Default, i));
builder.Field(CreateField(Date32Type.Default, i));
builder.Field(CreateField(Date64Type.Default, i));
+ builder.Field(CreateField(Time32Type.Default, i));
+ builder.Field(CreateField(Time64Type.Default, i));
builder.Field(CreateField(TimestampType.Default, i));
builder.Field(CreateField(StringType.Default, i));
builder.Field(CreateField(new StructType(new List<Field> { CreateField(StringType.Default, i), CreateField(Int32Type.Default, i) }), i));
@@ -61,8 +63,6 @@ namespace Apache.Arrow.Tests
//builder.Field(CreateField(HalfFloatType.Default));
//builder.Field(CreateField(StringType.Default));
- //builder.Field(CreateField(Time32Type.Default));
- //builder.Field(CreateField(Time64Type.Default));
}
Schema schema = builder.Build();
@@ -107,6 +107,8 @@ namespace Apache.Arrow.Tests
IArrowTypeVisitor<BooleanType>,
IArrowTypeVisitor<Date32Type>,
IArrowTypeVisitor<Date64Type>,
+ IArrowTypeVisitor<Time32Type>,
+ IArrowTypeVisitor<Time64Type>,
IArrowTypeVisitor<Int8Type>,
IArrowTypeVisitor<Int16Type>,
IArrowTypeVisitor<Int32Type>,
@@ -199,6 +201,30 @@ namespace Apache.Arrow.Tests
Array = builder.Build();
}
+ public void Visit(Time32Type type)
+ {
+ var builder = new Time32Array.Builder(type).Reserve(Length);
+
+ for (var i = 0; i < Length; i++)
+ {
+ builder.Append(i);
+ }
+
+ Array = builder.Build();
+ }
+
+ public void Visit(Time64Type type)
+ {
+ var builder = new Time64Array.Builder(type).Reserve(Length);
+
+ for (var i = 0; i < Length; i++)
+ {
+ builder.Append(i);
+ }
+
+ Array = builder.Build();
+ }
+
public void Visit(TimestampType type)
{
var builder = new TimestampArray.Builder().Reserve(Length);
diff --git a/dev/archery/archery/integration/datagen.py b/dev/archery/archery/integration/datagen.py
index 4221307382..972f4c8265 100644
--- a/dev/archery/archery/integration/datagen.py
+++ b/dev/archery/archery/integration/datagen.py
@@ -1605,8 +1605,7 @@ def get_generated_json_files(tempdir=None):
.skip_category('JS')
.skip_category('Rust'),
- generate_datetime_case()
- .skip_category('C#'),
+ generate_datetime_case(),
generate_duration_case()
.skip_category('C#')
diff --git a/docs/source/status.rst b/docs/source/status.rst
index 6ea657fc5d..95f018980b 100644
--- a/docs/source/status.rst
+++ b/docs/source/status.rst
@@ -49,7 +49,7 @@ Data Types
+-------------------+-------+-------+-------+------------+-------+-------+-------+
| Date32/64 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+-------------------+-------+-------+-------+------------+-------+-------+-------+
-| Time32/64 | ✓ | ✓ | ✓ | ✓ | | ✓ | ✓ |
+| Time32/64 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+-------------------+-------+-------+-------+------------+-------+-------+-------+
| Timestamp | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+-------------------+-------+-------+-------+------------+-------+-------+-------+