forked from apache/arrow
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
apacheGH-38316: [C#] Implement interval types (apache#39043)
### What changes are included in this PR? Changes required to support the three interval types in the C# implementation. ### Are these changes tested? Yes. ### Are there any user-facing changes? Adds new classes for interval support. * Closes: apache#38316 * Closes: apache#29431 Lead-authored-by: Curt Hagenlocher <[email protected]> Co-authored-by: Platob <[email protected]> Signed-off-by: Curt Hagenlocher <[email protected]>
- Loading branch information
Showing
22 changed files
with
883 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// 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; | ||
using Apache.Arrow.Scalars; | ||
using Apache.Arrow.Types; | ||
|
||
namespace Apache.Arrow | ||
{ | ||
internal static class IntervalArray | ||
{ | ||
internal static IArrowArray Create(ArrayData data) => ((IntervalType)data.DataType).Unit switch | ||
{ | ||
IntervalUnit.YearMonth => new YearMonthIntervalArray(data), | ||
IntervalUnit.DayTime => new DayTimeIntervalArray(data), | ||
IntervalUnit.MonthDayNanosecond => new MonthDayNanosecondIntervalArray(data), | ||
_ => throw new InvalidOperationException($"Unsupported interval unit {((IntervalType)data.DataType).Unit}"), | ||
}; | ||
} | ||
|
||
public abstract class IntervalArray<T> : PrimitiveArray<T> | ||
where T : struct | ||
{ | ||
protected IntervalArray(ArrayData data) | ||
: base(data) | ||
{ | ||
data.EnsureBufferCount(2); | ||
data.EnsureDataType(ArrowTypeId.Interval); | ||
} | ||
|
||
public IntervalType Type => (IntervalType)Data.DataType; | ||
|
||
public IntervalUnit Unit => Type.Unit; | ||
|
||
internal static IArrowArray Create(ArrayData data) => ((IntervalType)data.DataType).Unit switch | ||
{ | ||
IntervalUnit.YearMonth => new YearMonthIntervalArray(data), | ||
IntervalUnit.DayTime => new DayTimeIntervalArray(data), | ||
IntervalUnit.MonthDayNanosecond => new MonthDayNanosecondIntervalArray(data), | ||
_ => throw new InvalidOperationException($"Unsupported interval unit {((IntervalType)data.DataType).Unit}"), | ||
}; | ||
|
||
internal static void ValidateUnit(IntervalUnit expected, IntervalUnit actual) | ||
{ | ||
if (expected != actual) | ||
{ | ||
throw new ArgumentException( | ||
$"Specified interval unit <{actual}> does not match expected unit <{expected}>", | ||
"Unit"); | ||
} | ||
} | ||
} | ||
|
||
public sealed class YearMonthIntervalArray : IntervalArray<YearMonthInterval> | ||
{ | ||
public class Builder : PrimitiveArrayBuilder<YearMonthInterval, YearMonthIntervalArray, Builder> | ||
{ | ||
protected override YearMonthIntervalArray Build( | ||
ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, | ||
int length, int nullCount, int offset) => | ||
new YearMonthIntervalArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset); | ||
} | ||
|
||
public YearMonthIntervalArray( | ||
ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, | ||
int length, int nullCount, int offset) | ||
: this(new ArrayData(IntervalType.YearMonth, length, nullCount, offset, | ||
new[] { nullBitmapBuffer, valueBuffer })) | ||
{ } | ||
|
||
public YearMonthIntervalArray(ArrayData data) : base(data) | ||
{ | ||
ValidateUnit(IntervalUnit.YearMonth, Unit); | ||
} | ||
|
||
public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor); | ||
} | ||
|
||
public sealed class DayTimeIntervalArray : IntervalArray<DayTimeInterval> | ||
{ | ||
public class Builder : PrimitiveArrayBuilder<DayTimeInterval, DayTimeIntervalArray, Builder> | ||
{ | ||
protected override DayTimeIntervalArray Build( | ||
ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, | ||
int length, int nullCount, int offset) => | ||
new DayTimeIntervalArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset); | ||
} | ||
|
||
public DayTimeIntervalArray( | ||
ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, | ||
int length, int nullCount, int offset) | ||
: this(new ArrayData(IntervalType.DayTime, length, nullCount, offset, | ||
new[] { nullBitmapBuffer, valueBuffer })) | ||
{ } | ||
|
||
public DayTimeIntervalArray(ArrayData data) : base(data) | ||
{ | ||
ValidateUnit(IntervalUnit.DayTime, Unit); | ||
} | ||
|
||
public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor); | ||
} | ||
|
||
public sealed class MonthDayNanosecondIntervalArray : IntervalArray<MonthDayNanosecondInterval> | ||
{ | ||
public class Builder : PrimitiveArrayBuilder<MonthDayNanosecondInterval, MonthDayNanosecondIntervalArray, Builder> | ||
{ | ||
protected override MonthDayNanosecondIntervalArray Build( | ||
ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, | ||
int length, int nullCount, int offset) => | ||
new MonthDayNanosecondIntervalArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset); | ||
} | ||
|
||
public MonthDayNanosecondIntervalArray( | ||
ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, | ||
int length, int nullCount, int offset) | ||
: this(new ArrayData(IntervalType.MonthDayNanosecond, length, nullCount, offset, | ||
new[] { nullBitmapBuffer, valueBuffer })) | ||
{ } | ||
|
||
public MonthDayNanosecondIntervalArray(ArrayData data) : base(data) | ||
{ | ||
ValidateUnit(IntervalUnit.MonthDayNanosecond, Unit); | ||
} | ||
|
||
public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// 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; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Apache.Arrow.Scalars | ||
{ | ||
[StructLayout(LayoutKind.Explicit)] | ||
public struct DayTimeInterval : IEquatable<DayTimeInterval> | ||
{ | ||
[FieldOffset(0)] | ||
public readonly int Days; | ||
|
||
[FieldOffset(4)] | ||
public readonly int Milliseconds; | ||
|
||
public DayTimeInterval(int days, int milliseconds) | ||
{ | ||
Days = days; | ||
Milliseconds = milliseconds; | ||
} | ||
|
||
public override bool Equals(object obj) => obj switch | ||
{ | ||
DayTimeInterval interval => Equals(interval), | ||
_ => false, | ||
}; | ||
|
||
public override int GetHashCode() => unchecked((17 + Days) * 23 + Milliseconds); | ||
|
||
public bool Equals(DayTimeInterval interval) | ||
{ | ||
return this.Days == interval.Days && this.Milliseconds == interval.Milliseconds; | ||
} | ||
|
||
public static DateTime operator +(DateTime dateTime, DayTimeInterval interval) | ||
=> dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds); | ||
public static DateTime operator +(DayTimeInterval interval, DateTime dateTime) | ||
=> dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds); | ||
public static DateTime operator -(DateTime dateTime, DayTimeInterval interval) | ||
=> dateTime.AddDays(-interval.Days).AddMilliseconds(-interval.Milliseconds); | ||
|
||
public static DateTimeOffset operator +(DateTimeOffset dateTime, DayTimeInterval interval) | ||
=> dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds); | ||
public static DateTimeOffset operator +(DayTimeInterval interval, DateTimeOffset dateTime) | ||
=> dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds); | ||
public static DateTimeOffset operator -(DateTimeOffset dateTime, DayTimeInterval interval) | ||
=> dateTime.AddDays(-interval.Days).AddMilliseconds(-interval.Milliseconds); | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
csharp/src/Apache.Arrow/Scalars/MonthDayNanosecondInterval.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// 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; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Apache.Arrow.Scalars | ||
{ | ||
[StructLayout(LayoutKind.Explicit)] | ||
public struct MonthDayNanosecondInterval : IEquatable<MonthDayNanosecondInterval> | ||
{ | ||
[FieldOffset(0)] | ||
public readonly int Months; | ||
|
||
[FieldOffset(4)] | ||
public readonly int Days; | ||
|
||
[FieldOffset(8)] | ||
public readonly long Nanoseconds; | ||
|
||
public MonthDayNanosecondInterval(int months, int days, long nanoseconds) | ||
{ | ||
Months = months; | ||
Days = days; | ||
Nanoseconds = nanoseconds; | ||
} | ||
|
||
public override bool Equals(object obj) => obj switch | ||
{ | ||
MonthDayNanosecondInterval interval => Equals(interval), | ||
_ => false, | ||
}; | ||
|
||
public override int GetHashCode() => unchecked(((17 + Months) * 23 + Days) * 23 + (int)Nanoseconds); | ||
|
||
public bool Equals(MonthDayNanosecondInterval interval) | ||
{ | ||
return this.Months == interval.Months && this.Days == interval.Days && this.Nanoseconds == interval.Nanoseconds; | ||
} | ||
|
||
public static DateTime operator +(DateTime dateTime, MonthDayNanosecondInterval interval) | ||
=> dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100); | ||
public static DateTime operator +(MonthDayNanosecondInterval interval, DateTime dateTime) | ||
=> dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100); | ||
public static DateTime operator -(DateTime dateTime, MonthDayNanosecondInterval interval) | ||
=> dateTime.AddMonths(-interval.Months).AddDays(-interval.Days).AddTicks(-interval.Nanoseconds / 100); | ||
|
||
public static DateTimeOffset operator +(DateTimeOffset dateTime, MonthDayNanosecondInterval interval) | ||
=> dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100); | ||
public static DateTimeOffset operator +(MonthDayNanosecondInterval interval, DateTimeOffset dateTime) | ||
=> dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100); | ||
public static DateTimeOffset operator -(DateTimeOffset dateTime, MonthDayNanosecondInterval interval) | ||
=> dateTime.AddMonths(-interval.Months).AddDays(-interval.Days).AddTicks(-interval.Nanoseconds / 100); | ||
} | ||
} |
Oops, something went wrong.