Skip to content

Commit 4638265

Browse files
committed
fix extract functions
1 parent fd6b865 commit 4638265

File tree

2 files changed

+52
-27
lines changed

2 files changed

+52
-27
lines changed

enginetest/queries/function_queries.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,6 +2127,22 @@ var FunctionQueryTests = []QueryTest{
21272127
ExpectedWarning: mysql.ERTruncatedWrongValue,
21282128
ExpectedWarningsCount: 1,
21292129
},
2130+
{
2131+
Query: "select extract(week from 0)",
2132+
// This is 613566757 in MySQL but that value seems related to this bug https://bugs.mysql.com/bug.php?id=71414&files=1
2133+
Expected: []sql.Row{{1}},
2134+
},
2135+
{
2136+
Query: "select extract(week from false)",
2137+
// This is 613566757 in MySQL but that value seems related to this bug https://bugs.mysql.com/bug.php?id=71414&files=1
2138+
Expected: []sql.Row{{1}},
2139+
},
2140+
{
2141+
Query: "select extract(week from true)",
2142+
Expected: []sql.Row{{nil}},
2143+
ExpectedWarning: mysql.ERTruncatedWrongValue,
2144+
ExpectedWarningsCount: 1,
2145+
},
21302146
{
21312147
Query: "select extract(month from 0)",
21322148
Expected: []sql.Row{{0}},

sql/expression/function/extract.go

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (td *Extract) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
114114

115115
switch unit {
116116
case "DAY":
117-
return dateTime.Day(), nil
117+
return day(dateTime), nil
118118
case "HOUR":
119119
return dateTime.Hour(), nil
120120
case "MINUTE":
@@ -124,27 +124,19 @@ func (td *Extract) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
124124
case "MICROSECOND":
125125
return dateTime.Nanosecond() / 1000, nil
126126
case "QUARTER":
127-
return (int(dateTime.Month())-1)/3 + 1, nil
127+
return quarter(dateTime), nil
128128
case "MONTH":
129-
return int(dateTime.Month()), nil
129+
return month(dateTime), nil
130130
case "WEEK":
131-
dateVal, err := td.RightChild.Eval(ctx, row)
132-
if err != nil {
133-
return nil, err
134-
}
135-
date, err := getDate(ctx, dateVal)
136-
if err != nil {
137-
return nil, err
138-
}
139-
yyyy, ok := year(date).(int)
131+
yyyy, ok := year(dateTime).(int)
140132
if !ok {
141133
return nil, sql.ErrInvalidArgumentDetails.New("WEEK", "invalid year")
142134
}
143-
mm, ok := month(date).(int)
135+
mm, ok := month(dateTime).(int)
144136
if !ok {
145137
return nil, sql.ErrInvalidArgumentDetails.New("WEEK", "invalid month")
146138
}
147-
dd, ok := day(date).(int)
139+
dd, ok := day(dateTime).(int)
148140
if !ok {
149141
return nil, sql.ErrInvalidArgumentDetails.New("WEEK", "invalid day")
150142
}
@@ -157,29 +149,41 @@ func (td *Extract) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
157149
}
158150
return int(week), nil
159151
case "YEAR":
160-
return dateTime.Year(), nil
152+
return year(dateTime), nil
161153
case "DAY_HOUR":
162-
dd := dateTime.Day() * 1_00
154+
dd, ok := day(dateTime).(int)
155+
if !ok {
156+
return nil, sql.ErrInvalidArgumentDetails.New("DAY_HOUR", "invalid day")
157+
}
163158
hh := dateTime.Hour()
164-
return dd + hh, nil
159+
return (dd * 1_00) + hh, nil
165160
case "DAY_MINUTE":
166-
dd := dateTime.Day() * 1_00_00
161+
dd, ok := day(dateTime).(int)
162+
if !ok {
163+
return nil, sql.ErrInvalidArgumentDetails.New("DAY_MINUTE", "invalid day")
164+
}
167165
hh := dateTime.Hour() * 1_00
168166
mm := dateTime.Minute()
169-
return dd + hh + mm, nil
167+
return (dd * 1_00_00) + hh + mm, nil
170168
case "DAY_SECOND":
171-
dd := dateTime.Day() * 1_00_00_00
169+
dd, ok := day(dateTime).(int)
170+
if !ok {
171+
return nil, sql.ErrInvalidArgumentDetails.New("DAY_SECOND", "invalid day")
172+
}
172173
hh := dateTime.Hour() * 1_00_00
173174
mm := dateTime.Minute() * 1_00
174175
ss := dateTime.Second()
175-
return dd + hh + mm + ss, nil
176+
return (dd * 1_00_00_00) + hh + mm + ss, nil
176177
case "DAY_MICROSECOND":
177-
dd := dateTime.Day() * 1_00_00_00_000000
178+
dd, ok := day(dateTime).(int)
179+
if !ok {
180+
return nil, sql.ErrInvalidArgumentDetails.New("DAY_MICROSECOND", "invalid day")
181+
}
178182
hh := dateTime.Hour() * 1_00_00_000000
179183
mm := dateTime.Minute() * 1_00_000000
180184
ss := dateTime.Second() * 1_000000
181185
mmmmmm := dateTime.Nanosecond() / 1000
182-
return dd + hh + mm + ss + mmmmmm, nil
186+
return (dd * 1_00_00_00_000000) + hh + mm + ss + mmmmmm, nil
183187
case "HOUR_MINUTE":
184188
hh := dateTime.Hour() * 1_00
185189
mm := dateTime.Minute()
@@ -209,10 +213,15 @@ func (td *Extract) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
209213
mmmmmm := dateTime.Nanosecond() / 1000
210214
return ss + mmmmmm, nil
211215
case "YEAR_MONTH":
212-
yyyy := dateTime.Year() * 1_00
213-
dateTime.Month()
214-
mm := int(dateTime.Month())
215-
return yyyy + mm, nil
216+
yyyy, ok := year(dateTime).(int)
217+
if !ok {
218+
return nil, sql.ErrInvalidArgumentDetails.New("YEAR_MONTH", "invalid year")
219+
}
220+
mm, ok := month(dateTime).(int)
221+
if !ok {
222+
return nil, sql.ErrInvalidArgumentDetails.New("YEAR_MONTH", "invalid month")
223+
}
224+
return (yyyy * 1_00) + mm, nil
216225
default:
217226
return nil, fmt.Errorf("invalid time unit")
218227
}

0 commit comments

Comments
 (0)