Support empty tags for all WHERE equality operations
A missing tag on a point was sometimes treated as `""` and sometimes treated as a separate `null` entity. This change modifies the equality operations to always treat a missing tag as an empty string. Empty tags are *not* indexed and do not have the same performance as a tag that exists. Fixes #3773.pull/6283/head
parent
ca534bf09f
commit
5bdd61bde7
|
@ -13,6 +13,7 @@
|
|||
- [#6223](https://github.com/influxdata/influxdb/issues/6223): Failure to start/run on Windows. Thanks @mvadu
|
||||
- [#6229](https://github.com/influxdata/influxdb/issues/6229): Fixed aggregate queries with no GROUP BY to include the end time.
|
||||
- [#6283](https://github.com/influxdata/influxdb/pull/6283): Fix GROUP BY tag to produce consistent results when a series has no tags.
|
||||
- [#3773](https://github.com/influxdata/influxdb/issues/3773): Support empty tags for all WHERE equality operations.
|
||||
|
||||
## v0.12.0 [2016-04-05]
|
||||
### Release Notes
|
||||
|
|
71
tsdb/meta.go
71
tsdb/meta.go
|
@ -763,13 +763,8 @@ func (m *Measurement) idsForExpr(n *influxql.BinaryExpr) (SeriesIDs, influxql.Ex
|
|||
return m.seriesIDs, n, nil
|
||||
}
|
||||
|
||||
tagVals, ok := m.seriesByTagKeyValue[name.Val]
|
||||
if name.Val != "_name" && !ok {
|
||||
if n.Op == influxql.NEQ || n.Op == influxql.NEQREGEX {
|
||||
return m.seriesIDs, &influxql.BooleanLiteral{Val: true}, nil
|
||||
}
|
||||
return nil, nil, nil
|
||||
}
|
||||
// Retrieve list of series with this tag key.
|
||||
tagVals := m.seriesByTagKeyValue[name.Val]
|
||||
|
||||
// if we're looking for series with a specific tag value
|
||||
if str, ok := value.(*influxql.StringLiteral); ok {
|
||||
|
@ -784,10 +779,23 @@ func (m *Measurement) idsForExpr(n *influxql.BinaryExpr) (SeriesIDs, influxql.Ex
|
|||
}
|
||||
|
||||
if n.Op == influxql.EQ {
|
||||
// return series that have a tag of specific value.
|
||||
ids = tagVals[str.Val]
|
||||
if str.Val != "" {
|
||||
// return series that have a tag of specific value.
|
||||
ids = tagVals[str.Val]
|
||||
} else {
|
||||
ids = m.seriesIDs
|
||||
for k := range tagVals {
|
||||
ids = ids.Reject(tagVals[k])
|
||||
}
|
||||
}
|
||||
} else if n.Op == influxql.NEQ {
|
||||
ids = m.seriesIDs.Reject(tagVals[str.Val])
|
||||
if str.Val != "" {
|
||||
ids = m.seriesIDs.Reject(tagVals[str.Val])
|
||||
} else {
|
||||
for k := range tagVals {
|
||||
ids = ids.Union(tagVals[k])
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids, &influxql.BooleanLiteral{Val: true}, nil
|
||||
}
|
||||
|
@ -805,19 +813,38 @@ func (m *Measurement) idsForExpr(n *influxql.BinaryExpr) (SeriesIDs, influxql.Ex
|
|||
return nil, &influxql.BooleanLiteral{Val: true}, nil
|
||||
}
|
||||
|
||||
// The operation is a NEQREGEX, code must start by assuming all match, even
|
||||
// series without any tags.
|
||||
if n.Op == influxql.NEQREGEX {
|
||||
// Check if we match the empty string to see if we should include series
|
||||
// that are missing the tag.
|
||||
empty := re.Val.MatchString("")
|
||||
|
||||
// Gather the series that match the regex. If we should include the empty string,
|
||||
// start with the list of all series and reject series that don't match our condition.
|
||||
// If we should not include the empty string, include series that match our condition.
|
||||
if empty && n.Op == influxql.EQREGEX {
|
||||
ids = m.seriesIDs
|
||||
}
|
||||
|
||||
for k := range tagVals {
|
||||
match := re.Val.MatchString(k)
|
||||
|
||||
if match && n.Op == influxql.EQREGEX {
|
||||
ids = ids.Union(tagVals[k])
|
||||
} else if match && n.Op == influxql.NEQREGEX {
|
||||
ids = ids.Reject(tagVals[k])
|
||||
for k := range tagVals {
|
||||
if !re.Val.MatchString(k) {
|
||||
ids = ids.Reject(tagVals[k])
|
||||
}
|
||||
}
|
||||
} else if empty && n.Op == influxql.NEQREGEX {
|
||||
for k := range tagVals {
|
||||
if !re.Val.MatchString(k) {
|
||||
ids = ids.Union(tagVals[k])
|
||||
}
|
||||
}
|
||||
} else if !empty && n.Op == influxql.EQREGEX {
|
||||
for k := range tagVals {
|
||||
if re.Val.MatchString(k) {
|
||||
ids = ids.Union(tagVals[k])
|
||||
}
|
||||
}
|
||||
} else if !empty && n.Op == influxql.NEQREGEX {
|
||||
ids = m.seriesIDs
|
||||
for k := range tagVals {
|
||||
if re.Val.MatchString(k) {
|
||||
ids = ids.Reject(tagVals[k])
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids, &influxql.BooleanLiteral{Val: true}, nil
|
||||
|
|
Loading…
Reference in New Issue