Fix the time range when an exact timestamp is selected
There is a lot of confusion in the code if the range is [start, end) or [start, end]. This is not made easier because it is acts one way in some areas and in another way in some other areas, but it is usually [start, end]. The `time = ?` syntax assumed that it was [start, end) and added an extra nanosecond to the end time to accomodate for that, but the range was actually [start, end] and that caused it to include one extra nanosecond when it shouldn't have. This change fixes it so exactly one timestamp is selected when `time = ?` is used.pull/8098/head
parent
bf523c0513
commit
33981277bc
|
@ -23,6 +23,7 @@
|
||||||
- [#8155](https://github.com/influxdata/influxdb/pull/8155): Simplify admin user check.
|
- [#8155](https://github.com/influxdata/influxdb/pull/8155): Simplify admin user check.
|
||||||
- [#8118](https://github.com/influxdata/influxdb/issues/8118): Significantly improve DROP DATABASE speed.
|
- [#8118](https://github.com/influxdata/influxdb/issues/8118): Significantly improve DROP DATABASE speed.
|
||||||
- [#8181](https://github.com/influxdata/influxdb/issues/8181): Return an error when an invalid duration literal is parsed.
|
- [#8181](https://github.com/influxdata/influxdb/issues/8181): Return an error when an invalid duration literal is parsed.
|
||||||
|
- [#8093](https://github.com/influxdata/influxdb/issues/8093): Fix the time range when an exact timestamp is selected.
|
||||||
|
|
||||||
## v1.2.2 [2017-03-14]
|
## v1.2.2 [2017-03-14]
|
||||||
|
|
||||||
|
|
|
@ -3957,8 +3957,8 @@ func TimeRange(expr Expr) (min, max time.Time, err error) {
|
||||||
if min.IsZero() || value.After(min) {
|
if min.IsZero() || value.After(min) {
|
||||||
min = value
|
min = value
|
||||||
}
|
}
|
||||||
if max.IsZero() || value.Add(1*time.Nanosecond).Before(max) {
|
if max.IsZero() || value.Before(max) {
|
||||||
max = value.Add(1 * time.Nanosecond)
|
max = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -879,7 +879,7 @@ func TestTimeRange(t *testing.T) {
|
||||||
{expr: `time < 10`, min: `0001-01-01T00:00:00Z`, max: `1970-01-01T00:00:00.000000009Z`},
|
{expr: `time < 10`, min: `0001-01-01T00:00:00Z`, max: `1970-01-01T00:00:00.000000009Z`},
|
||||||
|
|
||||||
// Equality
|
// Equality
|
||||||
{expr: `time = '2000-01-01 00:00:00'`, min: `2000-01-01T00:00:00Z`, max: `2000-01-01T00:00:00.000000001Z`},
|
{expr: `time = '2000-01-01 00:00:00'`, min: `2000-01-01T00:00:00Z`, max: `2000-01-01T00:00:00Z`},
|
||||||
|
|
||||||
// Multiple time expressions.
|
// Multiple time expressions.
|
||||||
{expr: `time >= '2000-01-01 00:00:00' AND time < '2000-01-02 00:00:00'`, min: `2000-01-01T00:00:00Z`, max: `2000-01-01T23:59:59.999999999Z`},
|
{expr: `time >= '2000-01-01 00:00:00' AND time < '2000-01-02 00:00:00'`, min: `2000-01-01T00:00:00Z`, max: `2000-01-01T23:59:59.999999999Z`},
|
||||||
|
@ -888,7 +888,7 @@ func TestTimeRange(t *testing.T) {
|
||||||
{expr: `time >= '2000-01-01 00:00:00' AND time <= '1999-01-01 00:00:00'`, min: `2000-01-01T00:00:00Z`, max: `1999-01-01T00:00:00Z`},
|
{expr: `time >= '2000-01-01 00:00:00' AND time <= '1999-01-01 00:00:00'`, min: `2000-01-01T00:00:00Z`, max: `1999-01-01T00:00:00Z`},
|
||||||
|
|
||||||
// Absolute time
|
// Absolute time
|
||||||
{expr: `time = 1388534400s`, min: `2014-01-01T00:00:00Z`, max: `2014-01-01T00:00:00.000000001Z`},
|
{expr: `time = 1388534400s`, min: `2014-01-01T00:00:00Z`, max: `2014-01-01T00:00:00Z`},
|
||||||
|
|
||||||
// Non-comparative expressions.
|
// Non-comparative expressions.
|
||||||
{expr: `time`, min: `0001-01-01T00:00:00Z`, max: `0001-01-01T00:00:00Z`},
|
{expr: `time`, min: `0001-01-01T00:00:00Z`, max: `0001-01-01T00:00:00Z`},
|
||||||
|
|
|
@ -4356,6 +4356,60 @@ func TestServer_Query_AggregateSelectors(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServer_Query_ExactTimeRange(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
s := OpenServer(NewConfig())
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicySpec("rp0", 1, 0), true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
writes := []string{
|
||||||
|
fmt.Sprintf(`cpu value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00.000000000Z").UnixNano()),
|
||||||
|
fmt.Sprintf(`cpu value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00.000000001Z").UnixNano()),
|
||||||
|
fmt.Sprintf(`cpu value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00.000000002Z").UnixNano()),
|
||||||
|
}
|
||||||
|
|
||||||
|
test := NewTest("db0", "rp0")
|
||||||
|
test.writes = Writes{
|
||||||
|
&Write{data: strings.Join(writes, "\n")},
|
||||||
|
}
|
||||||
|
|
||||||
|
test.addQueries([]*Query{
|
||||||
|
&Query{
|
||||||
|
name: "query point at exactly one time - rfc3339nano",
|
||||||
|
params: url.Values{"db": []string{"db0"}},
|
||||||
|
command: `SELECT * FROM cpu WHERE time = '2000-01-01T00:00:00.000000001Z'`,
|
||||||
|
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00.000000001Z",2]]}]}]}`,
|
||||||
|
},
|
||||||
|
&Query{
|
||||||
|
name: "query point at exactly one time - timestamp",
|
||||||
|
params: url.Values{"db": []string{"db0"}},
|
||||||
|
command: `SELECT * FROM cpu WHERE time = 946684800000000001`,
|
||||||
|
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00.000000001Z",2]]}]}]}`,
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
|
||||||
|
for i, query := range test.queries {
|
||||||
|
if i == 0 {
|
||||||
|
if err := test.init(s); err != nil {
|
||||||
|
t.Fatalf("test init failed: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if query.skip {
|
||||||
|
t.Logf("SKIP:: %s", query.name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := query.Execute(s); err != nil {
|
||||||
|
t.Error(query.Error(err))
|
||||||
|
} else if !query.success() {
|
||||||
|
t.Error(query.failureMessage())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestServer_Query_Selectors(t *testing.T) {
|
func TestServer_Query_Selectors(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
s := OpenServer(NewConfig())
|
s := OpenServer(NewConfig())
|
||||||
|
|
Loading…
Reference in New Issue