Merge pull request #6616 from influxdata/js-6607-show-tag-values-with-negative-regex-in-where-clause

SHOW TAG VALUES accepts != and !~ in WHERE clause
pull/6529/head
Jonathan A. Sternberg 2016-05-16 09:22:49 -04:00
commit 274647b5b2
4 changed files with 42 additions and 5 deletions

View File

@ -16,6 +16,7 @@
- [#6604](https://github.com/influxdata/influxdb/pull/6604): Remove old cluster code
- [#6618](https://github.com/influxdata/influxdb/pull/6618): Optimize shard loading
- [#6629](https://github.com/influxdata/influxdb/issues/6629): query-log-enabled in config not ignored anymore.
- [#6607](https://github.com/influxdata/influxdb/issues/6607): SHOW TAG VALUES accepts != and !~ in WHERE clause.
## v0.13.0 [2016-05-12]

View File

@ -5496,7 +5496,19 @@ func TestServer_Query_ShowTagKeys(t *testing.T) {
&Query{
name: `show tag values with key and where does not match the regular expression`,
command: `SHOW TAG VALUES WITH KEY = region WHERE host !~ /server0[12]/`,
exp: `{"results":[{"series":[{"name":"disk","columns":["key","value"],"values":[["region","caeast"]]}]}]}`,
exp: `{"results":[{"series":[{"name":"disk","columns":["key","value"],"values":[["region","caeast"]]},{"name":"gpu","columns":["key","value"],"values":[["region","caeast"]]}]}]}`,
params: url.Values{"db": []string{"db0"}},
},
&Query{
name: `show tag values with key and where partially matches the regular expression`,
command: `SHOW TAG VALUES WITH KEY = host WHERE region =~ /us/`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"]]}]}]}`,
params: url.Values{"db": []string{"db0"}},
},
&Query{
name: `show tag values with key and where partially does not match the regular expression`,
command: `SHOW TAG VALUES WITH KEY = host WHERE region !~ /us/`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]},{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server03"]]}]}]}`,
params: url.Values{"db": []string{"db0"}},
},
&Query{

View File

@ -233,6 +233,10 @@ func (d *DatabaseIndex) TagsForSeries(key string) map[string]string {
// is true) against when there are no measurements because the expression
// wasn't evaluated (when the bool is false).
func (d *DatabaseIndex) measurementsByExpr(expr influxql.Expr) (Measurements, bool, error) {
if expr == nil {
return nil, false, nil
}
switch e := expr.(type) {
case *influxql.BinaryExpr:
switch e.Op {
@ -360,7 +364,7 @@ func (d *DatabaseIndex) measurementsByTagFilters(filters []*TagFilter) Measureme
tagMatch = true
}
} else {
// Else, the operator is regex and we have to check all tag
// Else, the operator is a regex and we have to check all tag
// values against the regular expression.
for tagVal := range tagVals {
if f.Regex.MatchString(tagVal) {

View File

@ -1205,7 +1205,22 @@ func NewTagValuesIterator(sh *Shard, opt influxql.IteratorOptions) (influxql.Ite
return nil, errors.New("a condition is required")
}
mms, ok, err := sh.index.measurementsByExpr(opt.Condition)
measurementExpr := influxql.CloneExpr(opt.Condition)
measurementExpr = influxql.Reduce(influxql.RewriteExpr(measurementExpr, func(e influxql.Expr) influxql.Expr {
switch e := e.(type) {
case *influxql.BinaryExpr:
switch e.Op {
case influxql.EQ, influxql.NEQ, influxql.EQREGEX, influxql.NEQREGEX:
tag, ok := e.LHS.(*influxql.VarRef)
if !ok || tag.Val != "_name" {
return nil
}
}
}
return e
}), nil)
mms, ok, err := sh.index.measurementsByExpr(measurementExpr)
if err != nil {
return nil, err
} else if !ok {
@ -1213,8 +1228,13 @@ func NewTagValuesIterator(sh *Shard, opt influxql.IteratorOptions) (influxql.Ite
sort.Sort(mms)
}
// If there are no measurements, return immediately.
if len(mms) == 0 {
return &tagValuesIterator{}, nil
}
filterExpr := influxql.CloneExpr(opt.Condition)
filterExpr = influxql.RewriteExpr(filterExpr, func(e influxql.Expr) influxql.Expr {
filterExpr = influxql.Reduce(influxql.RewriteExpr(filterExpr, func(e influxql.Expr) influxql.Expr {
switch e := e.(type) {
case *influxql.BinaryExpr:
switch e.Op {
@ -1226,7 +1246,7 @@ func NewTagValuesIterator(sh *Shard, opt influxql.IteratorOptions) (influxql.Ite
}
}
return e
})
}), nil)
var series []*Series
keys := newStringSet()