mirror of
https://github.com/minio/minio.git
synced 2025-04-01 02:03:42 -04:00
s3 select: fix date_diff behavior (#11786)
Fixes #11785 and adds tests for samples given.
This commit is contained in:
parent
642ba3f2d6
commit
e5a1a2a974
@ -337,6 +337,47 @@ func TestJSONQueries(t *testing.T) {
|
|||||||
}`,
|
}`,
|
||||||
wantResult: `{"element_type":"__elem__merfu","element_id":"d868aefe-ef9a-4be2-b9b2-c9fd89cc43eb","attributes":{"__attr__image_dpi":300,"__attr__image_size":[2550,3299],"__attr__image_index":2,"__attr__image_format":"JPEG","__attr__file_extension":"jpg","__attr__data":null}}`,
|
wantResult: `{"element_type":"__elem__merfu","element_id":"d868aefe-ef9a-4be2-b9b2-c9fd89cc43eb","attributes":{"__attr__image_dpi":300,"__attr__image_size":[2550,3299],"__attr__image_index":2,"__attr__image_format":"JPEG","__attr__file_extension":"jpg","__attr__data":null}}`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "date_diff_month",
|
||||||
|
query: `SELECT date_diff(MONTH, '2019-10-20T', '2020-01-20T') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":3}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "date_diff_month_neg",
|
||||||
|
query: `SELECT date_diff(MONTH, '2020-01-20T', '2019-10-20T') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":-3}`,
|
||||||
|
},
|
||||||
|
// Examples from https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-date.html#s3-glacier-select-sql-reference-date-diff
|
||||||
|
{
|
||||||
|
name: "date_diff_year",
|
||||||
|
query: `SELECT date_diff(year, '2010-01-01T', '2011-01-01T') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":1}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "date_diff_year",
|
||||||
|
query: `SELECT date_diff(month, '2010-01-01T', '2010-05T') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":4}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "date_diff_month_oney",
|
||||||
|
query: `SELECT date_diff(month, '2010T', '2011T') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":12}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "date_diff_month_neg",
|
||||||
|
query: `SELECT date_diff(month, '2011T', '2010T') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":-12}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "date_diff_days",
|
||||||
|
query: `SELECT date_diff(day, '2010-01-01T23:00:00Z', '2010-01-02T01:00:00Z') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":0}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "date_diff_days_one",
|
||||||
|
query: `SELECT date_diff(day, '2010-01-01T23:00:00Z', '2010-01-02T23:00:00Z') FROM S3Object LIMIT 1`,
|
||||||
|
wantResult: `{"_1":1}`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
defRequest := `<?xml version="1.0" encoding="UTF-8"?>
|
defRequest := `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
@ -135,10 +135,6 @@ func dateAdd(timePart string, qty float64, t time.Time) (*Value, error) {
|
|||||||
return FromTimestamp(t.Add(duration)), nil
|
return FromTimestamp(t.Add(duration)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
dayInNanoseconds = time.Hour * 24
|
|
||||||
)
|
|
||||||
|
|
||||||
// dateDiff computes the difference between two times in terms of the
|
// dateDiff computes the difference between two times in terms of the
|
||||||
// `timePart` which can be years, months, days, hours, minutes or
|
// `timePart` which can be years, months, days, hours, minutes or
|
||||||
// seconds. For difference in years, months or days, the time part,
|
// seconds. For difference in years, months or days, the time part,
|
||||||
@ -146,42 +142,30 @@ const (
|
|||||||
func dateDiff(timePart string, ts1, ts2 time.Time) (*Value, error) {
|
func dateDiff(timePart string, ts1, ts2 time.Time) (*Value, error) {
|
||||||
if ts2.Before(ts1) {
|
if ts2.Before(ts1) {
|
||||||
v, err := dateDiff(timePart, ts2, ts1)
|
v, err := dateDiff(timePart, ts2, ts1)
|
||||||
v.negate()
|
if err == nil {
|
||||||
|
v.negate()
|
||||||
|
}
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
duration := ts2.Sub(ts1)
|
duration := ts2.Sub(ts1)
|
||||||
y1, m1, d1 := ts1.Date()
|
y1, m1, d1 := ts1.Date()
|
||||||
y2, m2, d2 := ts2.Date()
|
y2, m2, d2 := ts2.Date()
|
||||||
dy, dm := int64(y2-y1), int64(m2-m1)
|
|
||||||
|
|
||||||
switch timePart {
|
switch timePart {
|
||||||
case timePartYear:
|
case timePartYear:
|
||||||
|
dy := int64(y2 - y1)
|
||||||
if m2 > m1 || (m2 == m1 && d2 >= d1) {
|
if m2 > m1 || (m2 == m1 && d2 >= d1) {
|
||||||
return FromInt(dy), nil
|
return FromInt(dy), nil
|
||||||
}
|
}
|
||||||
return FromInt(dy - 1), nil
|
return FromInt(dy - 1), nil
|
||||||
case timePartMonth:
|
case timePartMonth:
|
||||||
months := 12 * dy
|
m1 += time.Month(12 * y1)
|
||||||
if m2 >= m1 {
|
m2 += time.Month(12 * y2)
|
||||||
months += dm
|
|
||||||
} else {
|
return FromInt(int64(m2 - m1)), nil
|
||||||
months += 12 + dm
|
|
||||||
}
|
|
||||||
if d2 < d1 {
|
|
||||||
months--
|
|
||||||
}
|
|
||||||
return FromInt(months), nil
|
|
||||||
case timePartDay:
|
case timePartDay:
|
||||||
// To compute the number of days between two times
|
return FromInt(int64(duration / (24 * time.Hour))), nil
|
||||||
// using the time package, zero out the time portions
|
|
||||||
// of the timestamps, compute the difference duration
|
|
||||||
// and then divide by the length of a day.
|
|
||||||
d1 := time.Date(y1, m1, d1, 0, 0, 0, 0, time.UTC)
|
|
||||||
d2 := time.Date(y2, m2, d2, 0, 0, 0, 0, time.UTC)
|
|
||||||
diff := d2.Sub(d1)
|
|
||||||
days := diff / dayInNanoseconds
|
|
||||||
return FromInt(int64(days)), nil
|
|
||||||
case timePartHour:
|
case timePartHour:
|
||||||
hours := duration / time.Hour
|
hours := duration / time.Hour
|
||||||
return FromInt(int64(hours)), nil
|
return FromInt(int64(hours)), nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user