forked from goccy/go-zetasqlite
/
function_interval.go
90 lines (83 loc) · 2.26 KB
/
function_interval.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package internal
import (
"fmt"
"cloud.google.com/go/bigquery"
)
func INTERVAL(value int64, part string) (Value, error) {
switch part {
case "YEAR":
return &IntervalValue{IntervalValue: &bigquery.IntervalValue{Years: int32(value)}}, nil
case "MONTH":
return &IntervalValue{IntervalValue: &bigquery.IntervalValue{Months: int32(value)}}, nil
case "DAY":
return &IntervalValue{IntervalValue: &bigquery.IntervalValue{Days: int32(value)}}, nil
case "HOUR":
return &IntervalValue{IntervalValue: &bigquery.IntervalValue{Hours: int32(value)}}, nil
case "MINUTE":
return &IntervalValue{IntervalValue: &bigquery.IntervalValue{Minutes: int32(value)}}, nil
case "SECOND":
return &IntervalValue{IntervalValue: &bigquery.IntervalValue{Seconds: int32(value)}}, nil
case "NANOSECOND":
return &IntervalValue{IntervalValue: &bigquery.IntervalValue{SubSecondNanos: int32(value)}}, nil
}
return nil, fmt.Errorf("unexpected interval part: %s", part)
}
func MAKE_INTERVAL(year, month, day, hour, minute, second int64) (Value, error) {
return &IntervalValue{
IntervalValue: &bigquery.IntervalValue{
Years: int32(year),
Months: int32(month),
Days: int32(day),
Hours: int32(hour),
Minutes: int32(minute),
Seconds: int32(second),
},
}, nil
}
func JUSTIFY_DAYS(v *IntervalValue) (Value, error) {
if v.Days > 29 {
v.Months += v.Days / 30
v.Days = v.Days % 30
} else if v.Days < -29 {
v.Months += v.Days / 30
v.Days = v.Days % 30
}
if v.Months > 11 {
v.Months -= 12
v.Years++
} else if v.Months < -11 {
v.Months += 12
v.Years--
}
return v, nil
}
func JUSTIFY_HOURS(v *IntervalValue) (Value, error) {
if v.Seconds > 59 {
v.Minutes += v.Seconds / 60
v.Seconds = v.Seconds % 60
} else if v.Seconds < -59 {
v.Minutes += v.Seconds / 60
v.Seconds = v.Seconds % 60
}
if v.Minutes > 59 {
v.Hours += v.Minutes / 60
v.Minutes = v.Minutes % 60
} else if v.Minutes < -59 {
v.Hours += v.Hours / 60
v.Minutes = v.Minutes % 60
}
if v.Hours > 23 {
v.Days += v.Hours / 24
v.Hours = v.Hours % 24
} else if v.Hours < -23 {
v.Days += v.Hours / 24
v.Hours = v.Hours % 24
}
return v, nil
}
func JUSTIFY_INTERVAL(v *IntervalValue) (Value, error) {
if _, err := JUSTIFY_HOURS(v); err != nil {
return nil, err
}
return JUSTIFY_DAYS(v)
}