]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/go/arrow/scalar/temporal.go
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / go / arrow / scalar / temporal.go
CommitLineData
1d09f67e
TL
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package scalar
18
19import (
20 "fmt"
21 "reflect"
22 "time"
23 "unsafe"
24
25 "github.com/apache/arrow/go/v6/arrow"
26 "golang.org/x/xerrors"
27)
28
29type op int8
30
31const (
32 convDIVIDE = iota
33 convMULTIPLY
34)
35
36var timestampConversion = [...][4]struct {
37 op op
38 factor int64
39}{
40 arrow.Nanosecond: {
41 arrow.Nanosecond: {convMULTIPLY, int64(time.Nanosecond)},
42 arrow.Microsecond: {convDIVIDE, int64(time.Microsecond)},
43 arrow.Millisecond: {convDIVIDE, int64(time.Millisecond)},
44 arrow.Second: {convDIVIDE, int64(time.Second)},
45 },
46 arrow.Microsecond: {
47 arrow.Nanosecond: {convMULTIPLY, int64(time.Microsecond)},
48 arrow.Microsecond: {convMULTIPLY, 1},
49 arrow.Millisecond: {convDIVIDE, int64(time.Millisecond / time.Microsecond)},
50 arrow.Second: {convDIVIDE, int64(time.Second / time.Microsecond)},
51 },
52 arrow.Millisecond: {
53 arrow.Nanosecond: {convMULTIPLY, int64(time.Millisecond)},
54 arrow.Microsecond: {convMULTIPLY, int64(time.Millisecond / time.Microsecond)},
55 arrow.Millisecond: {convMULTIPLY, 1},
56 arrow.Second: {convDIVIDE, int64(time.Second / time.Millisecond)},
57 },
58 arrow.Second: {
59 arrow.Nanosecond: {convMULTIPLY, int64(time.Second)},
60 arrow.Microsecond: {convMULTIPLY, int64(time.Second / time.Microsecond)},
61 arrow.Millisecond: {convMULTIPLY, int64(time.Second / time.Millisecond)},
62 arrow.Second: {convMULTIPLY, 1},
63 },
64}
65
66func ConvertTimestampValue(in, out arrow.TimeUnit, value int64) int64 {
67 conv := timestampConversion[int(in)][int(out)]
68 switch conv.op {
69 case convMULTIPLY:
70 return value * conv.factor
71 case convDIVIDE:
72 return value / conv.factor
73 }
74
75 return 0
76}
77
78func temporalToString(s TemporalScalar) string {
79 switch s := s.(type) {
80 case *Date32:
81 return time.Unix(0, 0).UTC().AddDate(0, 0, int(s.Value)).Format("2006-01-02")
82 case *Date64:
83 days := int(int64(s.Value) / (time.Hour * 24).Milliseconds())
84 return time.Unix(0, 0).UTC().AddDate(0, 0, days).Format("2006-01-02")
85 case *Duration:
86 return fmt.Sprint(time.Duration(s.Value) * s.Unit().Multiplier())
87 case *Time32:
88 return time.Unix(0, int64(s.Value)*int64(s.Unit().Multiplier())).UTC().Format("15:04:05.999")
89 case *Time64:
90 return time.Unix(0, int64(s.Value)*int64(s.Unit().Multiplier())).UTC().Format("15:04:05.999999999")
91 case *Timestamp:
92 return time.Unix(0, int64(s.Value)*int64(s.Unit().Multiplier())).UTC().Format("2006-01-02 15:04:05.999999999")
93 }
94 return "..."
95}
96
97type TemporalScalar interface {
98 Scalar
99 temporal()
100}
101
102type Duration struct {
103 scalar
104 Value arrow.Duration
105}
106
107func (Duration) temporal() {}
108func (s *Duration) value() interface{} { return s.Value }
109func (s *Duration) CastTo(to arrow.DataType) (Scalar, error) { return castTemporal(s, to) }
110func (s *Duration) String() string {
111 if !s.Valid {
112 return "null"
113 }
114 val, err := s.CastTo(arrow.BinaryTypes.String)
115 if err != nil {
116 return "..."
117 }
118 return string(val.(*String).Value.Bytes())
119}
120
121func (s *Duration) equals(rhs Scalar) bool {
122 return s.Value == rhs.(*Duration).Value
123}
124
125func (s *Duration) Unit() arrow.TimeUnit {
126 return s.DataType().(*arrow.TimestampType).Unit
127}
128func (s *Duration) Data() []byte {
129 return (*[arrow.DurationSizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
130}
131
132func NewDurationScalar(val arrow.Duration, typ arrow.DataType) *Duration {
133 return &Duration{scalar{typ, true}, val}
134}
135
136type DateScalar interface {
137 TemporalScalar
138 date()
139}
140
141type TimeScalar interface {
142 TemporalScalar
143 Unit() arrow.TimeUnit
144 time()
145}
146
147type IntervalScalar interface {
148 TemporalScalar
149 interval()
150}
151
152const millisecondsInDay = (time.Hour * 24) / time.Millisecond
153
154func castTemporal(from TemporalScalar, to arrow.DataType) (Scalar, error) {
155 if arrow.TypeEqual(from.DataType(), to) {
156 return from, nil
157 }
158
159 if !from.IsValid() {
160 return MakeNullScalar(to), nil
161 }
162
163 if r, ok := numericMap[to.ID()]; ok {
164 return convertToNumeric(reflect.ValueOf(from.value()), r.valueType, r.scalarFunc), nil
165 }
166
167 if to.ID() == arrow.STRING {
168 return NewStringScalar(temporalToString(from)), nil
169 }
170
171 switch s := from.(type) {
172 case DateScalar:
173 if to.ID() == arrow.TIMESTAMP {
174 var newValue int64
175 switch s := s.(type) {
176 case *Date32:
177 newValue = int64(s.Value) * int64(millisecondsInDay)
178 case *Date64:
179 newValue = int64(s.Value)
180 }
181 return NewTimestampScalar(arrow.Timestamp(ConvertTimestampValue(arrow.Millisecond, to.(*arrow.TimestampType).Unit, newValue)), to), nil
182 }
183
184 switch s := s.(type) {
185 case *Date32:
186 if to.ID() == arrow.DATE64 {
187 return NewDate64Scalar(arrow.Date64(s.Value) * arrow.Date64(millisecondsInDay)), nil
188 }
189 case *Date64:
190 if to.ID() == arrow.DATE32 {
191 return NewDate32Scalar(arrow.Date32(s.Value / arrow.Date64(millisecondsInDay))), nil
192 }
193 }
194 case *Timestamp:
195 switch to := to.(type) {
196 case *arrow.TimestampType:
197 return NewTimestampScalar(arrow.Timestamp(ConvertTimestampValue(s.Unit(), to.Unit, int64(s.Value))), to), nil
198 case *arrow.Date32Type:
199 millis := ConvertTimestampValue(s.Unit(), arrow.Millisecond, int64(s.Value))
200 return NewDate32Scalar(arrow.Date32(millis / int64(millisecondsInDay))), nil
201 case *arrow.Date64Type:
202 millis := ConvertTimestampValue(s.Unit(), arrow.Millisecond, int64(s.Value))
203 return NewDate64Scalar(arrow.Date64(millis - millis%int64(millisecondsInDay))), nil
204 }
205 case TimeScalar:
206 switch to := to.(type) {
207 case *arrow.Time32Type:
208 return NewTime32Scalar(arrow.Time32(ConvertTimestampValue(s.Unit(), to.Unit, int64(s.value().(arrow.Time64)))), to), nil
209 case *arrow.Time64Type:
210 return NewTime64Scalar(arrow.Time64(ConvertTimestampValue(s.Unit(), to.Unit, int64(s.value().(arrow.Time32)))), to), nil
211 }
212
213 case *Duration:
214 switch to := to.(type) {
215 case *arrow.StringType:
216
217 case *arrow.DurationType:
218 return NewDurationScalar(arrow.Duration(ConvertTimestampValue(s.Unit(), to.Unit, int64(s.Value))), to), nil
219 }
220 }
221
222 return nil, xerrors.Errorf("")
223}
224
225type Date32 struct {
226 scalar
227 Value arrow.Date32
228}
229
230func (Date32) temporal() {}
231func (Date32) date() {}
232func (s *Date32) value() interface{} { return s.Value }
233func (s *Date32) Data() []byte {
234 return (*[arrow.Date32SizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
235}
236func (s *Date32) equals(rhs Scalar) bool {
237 return s.Value == rhs.(*Date32).Value
238}
239func (s *Date32) CastTo(to arrow.DataType) (Scalar, error) { return castTemporal(s, to) }
240func (s *Date32) String() string {
241 if !s.Valid {
242 return "null"
243 }
244 val, err := s.CastTo(arrow.BinaryTypes.String)
245 if err != nil {
246 return "..."
247 }
248 return string(val.(*String).Value.Bytes())
249}
250
251func NewDate32Scalar(val arrow.Date32) *Date32 {
252 return &Date32{scalar{arrow.FixedWidthTypes.Date32, true}, val}
253}
254
255type Date64 struct {
256 scalar
257 Value arrow.Date64
258}
259
260func (Date64) temporal() {}
261func (Date64) date() {}
262func (s *Date64) value() interface{} { return s.Value }
263func (s *Date64) CastTo(to arrow.DataType) (Scalar, error) { return castTemporal(s, to) }
264func (s *Date64) Data() []byte {
265 return (*[arrow.Date64SizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
266}
267func (s *Date64) equals(rhs Scalar) bool {
268 return s.Value == rhs.(*Date64).Value
269}
270func (s *Date64) String() string {
271 if !s.Valid {
272 return "null"
273 }
274 val, err := s.CastTo(arrow.BinaryTypes.String)
275 if err != nil {
276 return "..."
277 }
278 return string(val.(*String).Value.Bytes())
279}
280
281func NewDate64Scalar(val arrow.Date64) *Date64 {
282 return &Date64{scalar{arrow.FixedWidthTypes.Date64, true}, val}
283}
284
285type Time32 struct {
286 scalar
287 Value arrow.Time32
288}
289
290func (Time32) temporal() {}
291func (Time32) time() {}
292func (s *Time32) value() interface{} { return s.Value }
293func (s *Time32) CastTo(to arrow.DataType) (Scalar, error) { return castTemporal(s, to) }
294func (s *Time32) Unit() arrow.TimeUnit {
295 return s.DataType().(*arrow.Time32Type).Unit
296}
297func (s *Time32) equals(rhs Scalar) bool {
298 return s.Value == rhs.(*Time32).Value
299}
300func (s *Time32) String() string {
301 if !s.Valid {
302 return "null"
303 }
304 val, err := s.CastTo(arrow.BinaryTypes.String)
305 if err != nil {
306 return "..."
307 }
308 return string(val.(*String).Value.Bytes())
309}
310
311func (s *Time32) Data() []byte {
312 return (*[arrow.Time32SizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
313}
314
315func NewTime32Scalar(val arrow.Time32, typ arrow.DataType) *Time32 {
316 return &Time32{scalar{typ, true}, val}
317}
318
319type Time64 struct {
320 scalar
321 Value arrow.Time64
322}
323
324func (Time64) temporal() {}
325func (Time64) time() {}
326func (s *Time64) value() interface{} { return s.Value }
327func (s *Time64) CastTo(to arrow.DataType) (Scalar, error) { return castTemporal(s, to) }
328func (s *Time64) Unit() arrow.TimeUnit {
329 return s.DataType().(*arrow.Time64Type).Unit
330}
331func (s *Time64) Data() []byte {
332 return (*[arrow.Time64SizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
333}
334func (s *Time64) equals(rhs Scalar) bool {
335 return s.Value == rhs.(*Time64).Value
336}
337func (s *Time64) String() string {
338 if !s.Valid {
339 return "null"
340 }
341 val, err := s.CastTo(arrow.BinaryTypes.String)
342 if err != nil {
343 return "..."
344 }
345 return string(val.(*String).Value.Bytes())
346}
347
348func NewTime64Scalar(val arrow.Time64, typ arrow.DataType) *Time64 {
349 return &Time64{scalar{typ, true}, val}
350}
351
352type Timestamp struct {
353 scalar
354 Value arrow.Timestamp
355}
356
357func (Timestamp) temporal() {}
358func (Timestamp) time() {}
359func (s *Timestamp) value() interface{} { return s.Value }
360func (s *Timestamp) CastTo(to arrow.DataType) (Scalar, error) { return castTemporal(s, to) }
361func (s *Timestamp) Unit() arrow.TimeUnit {
362 return s.DataType().(*arrow.TimestampType).Unit
363}
364func (s *Timestamp) Data() []byte {
365 return (*[arrow.TimestampSizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
366}
367func (s *Timestamp) equals(rhs Scalar) bool {
368 return s.Value == rhs.(*Timestamp).Value
369}
370func (s *Timestamp) String() string {
371 if !s.Valid {
372 return "null"
373 }
374 val, err := s.CastTo(arrow.BinaryTypes.String)
375 if err != nil {
376 return "..."
377 }
378 return string(val.(*String).Value.Bytes())
379}
380
381func NewTimestampScalar(val arrow.Timestamp, typ arrow.DataType) *Timestamp {
382 return &Timestamp{scalar{typ, true}, val}
383}
384
385type MonthInterval struct {
386 scalar
387 Value arrow.MonthInterval
388}
389
390func (MonthInterval) temporal() {}
391func (MonthInterval) interval() {}
392func (s *MonthInterval) value() interface{} { return s.Value }
393func (s *MonthInterval) CastTo(to arrow.DataType) (Scalar, error) {
394 if !s.Valid {
395 return MakeNullScalar(to), nil
396 }
397
398 if !arrow.TypeEqual(s.DataType(), to) {
399 return nil, xerrors.Errorf("non-null monthinterval scalar cannot be cast to anything other than monthinterval")
400 }
401
402 return s, nil
403}
404func (s *MonthInterval) String() string {
405 if !s.Valid {
406 return "null"
407 }
408 val, err := s.CastTo(arrow.BinaryTypes.String)
409 if err != nil {
410 return "..."
411 }
412 return string(val.(*String).Value.Bytes())
413}
414func (s *MonthInterval) equals(rhs Scalar) bool {
415 return s.Value == rhs.(*MonthInterval).Value
416}
417func (s *MonthInterval) Data() []byte {
418 return (*[arrow.MonthIntervalSizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
419}
420
421func NewMonthIntervalScalar(val arrow.MonthInterval) *MonthInterval {
422 return &MonthInterval{scalar{arrow.FixedWidthTypes.MonthInterval, true}, val}
423}
424
425type DayTimeInterval struct {
426 scalar
427 Value arrow.DayTimeInterval
428}
429
430func (DayTimeInterval) temporal() {}
431func (DayTimeInterval) interval() {}
432func (s *DayTimeInterval) value() interface{} { return s.Value }
433func (s *DayTimeInterval) Data() []byte {
434 return (*[arrow.DayTimeIntervalSizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
435}
436func (s *DayTimeInterval) String() string {
437 if !s.Valid {
438 return "null"
439 }
440 val, err := s.CastTo(arrow.BinaryTypes.String)
441 if err != nil {
442 return "..."
443 }
444 return string(val.(*String).Value.Bytes())
445}
446
447func (s *DayTimeInterval) CastTo(to arrow.DataType) (Scalar, error) {
448 if !s.Valid {
449 return MakeNullScalar(to), nil
450 }
451
452 if !arrow.TypeEqual(s.DataType(), to) {
453 return nil, xerrors.Errorf("non-null daytimeinterval scalar cannot be cast to anything other than monthinterval")
454 }
455
456 return s, nil
457}
458
459func (s *DayTimeInterval) equals(rhs Scalar) bool {
460 return s.Value == rhs.(*DayTimeInterval).Value
461}
462
463func NewDayTimeIntervalScalar(val arrow.DayTimeInterval) *DayTimeInterval {
464 return &DayTimeInterval{scalar{arrow.FixedWidthTypes.DayTimeInterval, true}, val}
465}
466
467type MonthDayNanoInterval struct {
468 scalar
469 Value arrow.MonthDayNanoInterval
470}
471
472func (MonthDayNanoInterval) temporal() {}
473func (MonthDayNanoInterval) interval() {}
474func (s *MonthDayNanoInterval) value() interface{} { return s.Value }
475func (s *MonthDayNanoInterval) Data() []byte {
476 return (*[arrow.MonthDayNanoIntervalSizeBytes]byte)(unsafe.Pointer(&s.Value))[:]
477}
478func (s *MonthDayNanoInterval) String() string {
479 if !s.Valid {
480 return "null"
481 }
482 val, err := s.CastTo(arrow.BinaryTypes.String)
483 if err != nil {
484 return "..."
485 }
486 return string(val.(*String).Value.Bytes())
487}
488
489func (s *MonthDayNanoInterval) CastTo(to arrow.DataType) (Scalar, error) {
490 if !s.Valid {
491 return MakeNullScalar(to), nil
492 }
493
494 if !arrow.TypeEqual(s.DataType(), to) {
495 return nil, xerrors.Errorf("non-null month_day_nano_interval scalar cannot be cast to anything other than monthinterval")
496 }
497
498 return s, nil
499}
500
501func (s *MonthDayNanoInterval) equals(rhs Scalar) bool {
502 return s.Value == rhs.(*MonthDayNanoInterval).Value
503}
504
505func NewMonthDayNanoIntervalScalar(val arrow.MonthDayNanoInterval) *MonthDayNanoInterval {
506 return &MonthDayNanoInterval{scalar{arrow.FixedWidthTypes.MonthDayNanoInterval, true}, val}
507}
508
509var (
510 _ Scalar = (*Date32)(nil)
511)