Skip to content

Commit

Permalink
Merge pull request #2105 from influxdb/fix_tag_neq
Browse files Browse the repository at this point in the history
Fix tag NEQ
  • Loading branch information
otoolep committed Mar 31, 2015
2 parents ef409d6 + a7d9047 commit 3eb0b04
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- [#2100](https://github.com/influxdb/influxdb/pull/2100): Synchronize access to shard index.
- [#2131](https://github.com/influxdb/influxdb/pull/2131): Optimize marshalTags().
- [#2130](https://github.com/influxdb/influxdb/pull/2130): Make fewer calls to marshalTags().
- [#2105](https://github.com/influxdb/influxdb/pull/2105): Support != for tag values. Fix issue #2097, thanks to @smonkewitz for bug report.
- [#2105](https://github.com/influxdb/influxdb/pull/2105): Support !~ tags values.

## v0.9.0-rc17 [2015-03-29]

Expand Down
61 changes: 59 additions & 2 deletions cmd/influxd/server_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,16 +592,73 @@ func runTestsData(t *testing.T, testName string, nodes Cluster, database, retent
{
reset: true,
name: "WHERE tags SELECT single field (EQ tag value1)",
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [{"name": "cpu", "timestamp": "2015-02-28T01:03:36.703820946Z", "tags": {"host": "server01"}, "fields": {"value": 100}},
{"name": "cpu", "timestamp": "2010-02-28T01:03:37.703820946Z", "tags": {"host": "server02"}, "fields": {"value": 200}}]}`,
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [{"name": "cpu", "timestamp": "2015-02-28T01:03:36.703820946Z", "tags": {"host": "server01", "region": "us-west"}, "fields": {"value": 100}},
{"name": "cpu", "timestamp": "2010-02-28T01:03:37.703820946Z", "tags": {"host": "server02"}, "fields": {"value": 200}},
{"name": "cpu", "timestamp": "2012-02-28T01:03:38.703820946Z", "tags": {"host": "server03"}, "fields": {"value": 300}}]}`,
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host = 'server01'`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",100]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (2 EQ tags)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host = 'server01' AND region = 'us-west'`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",100]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (1 EQ and 1 NEQ tag)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host = 'server01' AND region != 'us-west'`,
expected: `{"results":[{}]}`,
},
{
name: "WHERE tags SELECT single field (EQ tag value2)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host = 'server02'`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2010-02-28T01:03:37.703820946Z",200]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (NEQ tag value1)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host != 'server01'`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2010-02-28T01:03:37.703820946Z",200],["2012-02-28T01:03:38.703820946Z",300]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (NEQ tag value1 AND NEQ tag value2)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host != 'server01' AND host != 'server02'`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",300]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (NEQ tag value1 OR NEQ tag value2)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host != 'server01' OR host != 'server02'`, // Yes, this is always true, but that's the point.
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2010-02-28T01:03:37.703820946Z",200],["2012-02-28T01:03:38.703820946Z",300],["2015-02-28T01:03:36.703820946Z",100]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (NEQ tag value1 AND NEQ tag value2 AND NEQ tag value3)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host != 'server01' AND host != 'server02' AND host != 'server03'`,
expected: `{"results":[{}]}`,
},
{
reset: true,
name: "WHERE tags SELECT single field (NEQ tag value1, point without any tags)",
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [{"name": "cpu", "timestamp": "2015-02-28T01:03:36.703820946Z", "tags": {"host": "server01"}, "fields": {"value": 100}},
{"name": "cpu", "timestamp": "2012-02-28T01:03:38.703820946Z", "fields": {"value": 200}}]}`,
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host != 'server01'`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",200]]}]}]}`,
},
{
reset: true,
name: "WHERE tags SELECT single field (regex tag no match)",
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [{"name": "cpu", "timestamp": "2015-02-28T01:03:36.703820946Z", "tags": {"host": "server01"}, "fields": {"value": 100}},
{"name": "cpu", "timestamp": "2012-02-28T01:03:38.703820946Z", "fields": {"value": 200}}]}`,
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host !~ /server01/`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",200]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (regex tag match)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host =~ /server01/`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",100]]}]}]}`,
},
{
name: "WHERE tags SELECT single field (regex tag match)",
query: `SELECT value FROM "%DB%"."%RP%".cpu WHERE host !~ /server[23]/`,
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",200],["2015-02-28T01:03:36.703820946Z",100]]}]}]}`,
},

// WHERE fields queries
{
Expand Down
21 changes: 19 additions & 2 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,19 +376,36 @@ func (m *Measurement) idsForExpr(n *influxql.BinaryExpr) (seriesIDs, bool, influ
return nil, true, nil
}

// if we're looking for series with a specific tag value
// if we're looking for series with specific tag values
if str, ok := value.(*influxql.StringLiteral); ok {
return tagVals[str.Val], true, nil
var ids seriesIDs

if n.Op == influxql.EQ {
// return series that have a tag of specific value.
ids = tagVals[str.Val]
} else if n.Op == influxql.NEQ {
ids = m.seriesIDs.reject(tagVals[str.Val])
}
return ids, true, nil
}

// if we're looking for series with tag values that match a regex
if re, ok := value.(*influxql.RegexLiteral); ok {
var ids seriesIDs

// The operation is a NEQREGEX, code must start by assuming all match, even
// series without any tags.
if n.Op == influxql.NEQREGEX {
ids = m.seriesIDs
}

for k := range tagVals {
match := re.Val.MatchString(k)

if (match && n.Op == influxql.EQREGEX) || (!match && n.Op == influxql.NEQREGEX) {
ids = ids.union(tagVals[k])
} else if match && n.Op == influxql.NEQREGEX {
ids = ids.reject(tagVals[k])
}
}
return ids, true, nil
Expand Down

0 comments on commit 3eb0b04

Please sign in to comment.