@@ -45,12 +45,12 @@ func isOffsetTypeOk(offsetType arrow.DataType) bool {
4545 case * arrow.DictionaryType :
4646 return arrow .IsInteger (offsetType .IndexType .ID ()) && arrow .TypeEqual (offsetType .ValueType , arrow .PrimitiveTypes .Int16 )
4747 case * arrow.RunEndEncodedType :
48- return offsetType .ValidRunEndsType (offsetType .RunEnds ()) &&
48+ return offsetType .ValidRunEndsType (offsetType .RunEnds ()) &&
4949 arrow .TypeEqual (offsetType .Encoded (), arrow .PrimitiveTypes .Int16 )
50- // FIXME: Technically this should be non-nullable, but a Arrow IPC does not deserialize
51- // ValueNullable properly, so enforcing this here would always fail when reading from an IPC
52- // stream
53- // !offsetType.ValueNullable
50+ // FIXME: Technically this should be non-nullable, but a Arrow IPC does not deserialize
51+ // ValueNullable properly, so enforcing this here would always fail when reading from an IPC
52+ // stream
53+ // !offsetType.ValueNullable
5454 default :
5555 return false
5656 }
@@ -66,10 +66,10 @@ func isDataTypeCompatible(storageType arrow.DataType) (unit arrow.TimeUnit, offs
6666
6767 st , compat := storageType .(* arrow.StructType )
6868 if ! compat || st .NumFields () != 2 {
69- return
69+ return
7070 }
7171
72- if ts , compat := st .Field (0 ).Type .(* arrow.TimestampType ); compat && ts .TimeZone == "UTC" {
72+ if ts , compat := st .Field (0 ).Type .(* arrow.TimestampType ); compat && ts .TimeZone == "UTC" {
7373 unit = ts .TimeUnit ()
7474 } else {
7575 return
@@ -126,8 +126,8 @@ func NewTimestampWithOffsetTypeCustomOffset(unit arrow.TimeUnit, offsetType arro
126126}
127127
128128type DictIndexType interface {
129- * arrow.Int8Type | * arrow.Int16Type | * arrow.Int32Type | * arrow.Int64Type |
130- * arrow.Uint8Type | * arrow.Uint16Type | * arrow.Uint32Type | * arrow.Uint64Type
129+ * arrow.Int8Type | * arrow.Int16Type | * arrow.Int32Type | * arrow.Int64Type |
130+ * arrow.Uint8Type | * arrow.Uint16Type | * arrow.Uint32Type | * arrow.Uint64Type
131131}
132132
133133// NewTimestampWithOffsetType creates a new TimestampWithOffsetType with the underlying storage type set correctly to
@@ -147,13 +147,11 @@ func NewTimestampWithOffsetTypeDictionaryEncoded[I DictIndexType](unit arrow.Tim
147147 return v
148148}
149149
150-
151150type TimestampWithOffsetRunEndsType interface {
152- * arrow.Int8Type | * arrow.Int16Type | * arrow.Int32Type | * arrow.Int64Type |
153- * arrow.Uint8Type | * arrow.Uint16Type | * arrow.Uint32Type | * arrow.Uint64Type
151+ * arrow.Int8Type | * arrow.Int16Type | * arrow.Int32Type | * arrow.Int64Type |
152+ * arrow.Uint8Type | * arrow.Uint16Type | * arrow.Uint32Type | * arrow.Uint64Type
154153}
155154
156-
157155// NewTimestampWithOffsetType creates a new TimestampWithOffsetType with the underlying storage type set correctly to
158156// Struct(timestamp=Timestamp(T, "UTC"), offset_minutes=RunEndEncoded(E, Int16)), where T is any TimeUnit and E is a
159157// valid run-ends type.
@@ -169,7 +167,6 @@ func NewTimestampWithOffsetTypeRunEndEncoded[E TimestampWithOffsetRunEndsType](u
169167
170168}
171169
172-
173170func (b * TimestampWithOffsetType ) ArrayType () reflect.Type {
174171 return reflect .TypeOf (TimestampWithOffsetArray {})
175172}
@@ -196,17 +193,20 @@ func (b *TimestampWithOffsetType) Deserialize(storageType arrow.DataType, data s
196193}
197194
198195func (b * TimestampWithOffsetType ) ExtensionEquals (other arrow.ExtensionType ) bool {
199- return b .ExtensionName () == other .ExtensionName ()
196+ return b .ExtensionName () == other .ExtensionName () &&
197+ arrow .TypeEqual (b .StorageType (), other .StorageType ())
198+ }
199+
200+ func (b * TimestampWithOffsetType ) OffsetType () arrow.DataType {
201+ return b .ExtensionBase .Storage .(* arrow.StructType ).Field (1 ).Type
200202}
201203
202204func (b * TimestampWithOffsetType ) TimeUnit () arrow.TimeUnit {
203205 return b .ExtensionBase .Storage .(* arrow.StructType ).Field (0 ).Type .(* arrow.TimestampType ).TimeUnit ()
204206}
205207
206208func (b * TimestampWithOffsetType ) NewBuilder (mem memory.Allocator ) array.Builder {
207- v , _ := NewTimestampWithOffsetBuilder (mem , b .TimeUnit (), arrow .PrimitiveTypes .Int16 )
208- // SAFETY: This will never error as Int16 is always a valid type for the offset field
209-
209+ v , _ := NewTimestampWithOffsetBuilder (mem , b .TimeUnit (), b .OffsetType ())
210210 return v
211211}
212212
@@ -295,7 +295,7 @@ func (a *TimestampWithOffsetArray) Value(i int) time.Time {
295295// If the timestamp is null, the returned time will be the unix epoch.
296296//
297297// This will iterate using the fastest method given the underlying storage array
298- func (a * TimestampWithOffsetArray ) iterValues () iter.Seq [time.Time ] {
298+ func (a * TimestampWithOffsetArray ) iterValues () iter.Seq [time.Time ] {
299299 return func (yield func (time.Time ) bool ) {
300300 structs := a .Storage ().(* array.Struct )
301301 offsets := structs .Field (1 )
@@ -322,26 +322,26 @@ func (a* TimestampWithOffsetArray) iterValues() iter.Seq[time.Time] {
322322 offsetPhysicalIdx += 1
323323 }
324324
325- ts := time .Unix (0 , 0 )
325+ ts := time .Unix (0 , 0 )
326326 if a .IsValid (i ) {
327327 utcTimestamp := timestamps .Value (i )
328328 offsetMinutes := offsetValues .Value (offsetPhysicalIdx )
329329 v := timeFromFieldValues (utcTimestamp , offsetMinutes , timeUnit )
330330 ts = v
331- }
331+ }
332332
333333 if ! yield (ts ) {
334334 return
335335 }
336336 }
337337 } else {
338338 for i := 0 ; i < a .Len (); i ++ {
339- ts := time .Unix (0 , 0 )
339+ ts := time .Unix (0 , 0 )
340340 if a .IsValid (i ) {
341341 utcTimestamp , offsetMinutes , timeUnit := a .rawValueUnsafe (i )
342342 v := timeFromFieldValues (utcTimestamp , offsetMinutes , timeUnit )
343343 ts = v
344- }
344+ }
345345
346346 if ! yield (ts ) {
347347 return
@@ -351,7 +351,6 @@ func (a* TimestampWithOffsetArray) iterValues() iter.Seq[time.Time] {
351351 }
352352}
353353
354-
355354func (a * TimestampWithOffsetArray ) Values () []time.Time {
356355 return slices .Collect (a .iterValues ())
357356}
@@ -409,7 +408,7 @@ func NewTimestampWithOffsetBuilder(mem memory.Allocator, unit arrow.TimeUnit, of
409408
410409 return & TimestampWithOffsetBuilder {
411410 unit : unit ,
412- offsetType : offsetType ,
411+ offsetType : offsetType ,
413412 lastOffset : math .MaxInt16 ,
414413 Layout : time .RFC3339 ,
415414 ExtensionBuilder : array .NewExtensionBuilder (mem , dataType ),
0 commit comments