Skip to content

Commit

Permalink
Fix subquery functionality when a function references a tag from the …
Browse files Browse the repository at this point in the history
…subquery

It has previously been allowed for a subquery to use a tag within a
function (such as `count()`) when the tag is from a subquery and the
subquery itself references a field at some point to perform the join.

This functionality regressed in 1.6 because of a change in how
subqueries were executed that forgot to treat a tag the same as a string
field.

This fixes that regression and adds a test case to avoid hitting that
regression again.
  • Loading branch information
jsternberg committed Oct 4, 2018
1 parent 05acc10 commit 634471f
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ v1.7.0 [unreleased]

- [#10005](https://github.com/influxdata/influxdb/pull/10005): Missing hardwareAddr in uuid v1 generation.
- [#10246](https://github.com/influxdata/influxdb/pull/10246): Fix the inherited interval for derivative and others.
- [#10333](https://github.com/influxdata/influxdb/pull/10333): Fix subquery functionality when a function references a tag from the subquery.

v1.6.0 [2018-07-05]
-------------------
Expand Down
2 changes: 1 addition & 1 deletion query/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func castToType(v interface{}, typ influxql.DataType) interface{} {
if val, ok := castToUnsigned(v); ok {
v = val
}
case influxql.String:
case influxql.String, influxql.Tag:
if val, ok := castToString(v); ok {
v = val
}
Expand Down
2 changes: 1 addition & 1 deletion query/iterator_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func NewIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt
return newIntegerIteratorMapper(cur, driver, fields, opt)
case influxql.Unsigned:
return newUnsignedIteratorMapper(cur, driver, fields, opt)
case influxql.String:
case influxql.String, influxql.Tag:
return newStringIteratorMapper(cur, driver, fields, opt)
case influxql.Boolean:
return newBooleanIteratorMapper(cur, driver, fields, opt)
Expand Down
35 changes: 35 additions & 0 deletions query/subquery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,41 @@ func TestSubquery(t *testing.T) {
{Time: 0 * Second, Series: query.Series{Name: "cpu"}, Values: []interface{}{int64(3)}},
},
},
{
Name: "CountTag",
Statement: `SELECT count(host) FROM (SELECT value, host FROM cpu) WHERE time >= '1970-01-01T00:00:00Z' AND time < '1970-01-01T00:00:15Z'`,
Fields: map[string]influxql.DataType{
"value": influxql.Float,
"host": influxql.Tag,
},
MapShardsFn: func(t *testing.T, tr influxql.TimeRange) CreateIteratorFn {
if got, want := tr.MinTimeNano(), 0*Second; got != want {
t.Errorf("unexpected min time: got=%d want=%d", got, want)
}
if got, want := tr.MaxTimeNano(), 15*Second-1; got != want {
t.Errorf("unexpected max time: got=%d want=%d", got, want)
}
return func(ctx context.Context, m *influxql.Measurement, opt query.IteratorOptions) query.Iterator {
if got, want := m.Name, "cpu"; got != want {
t.Errorf("unexpected source: got=%s want=%s", got, want)
}
if got, want := opt.Aux, []influxql.VarRef{
{Val: "host", Type: influxql.Tag},
{Val: "value", Type: influxql.Float},
}; !cmp.Equal(got, want) {
t.Errorf("unexpected auxiliary fields:\n%s", cmp.Diff(want, got))
}
return &FloatIterator{Points: []query.FloatPoint{
{Name: "cpu", Aux: []interface{}{"server01", 5.0}},
{Name: "cpu", Aux: []interface{}{"server02", 3.0}},
{Name: "cpu", Aux: []interface{}{"server03", 8.0}},
}}
}
},
Rows: []query.Row{
{Time: 0 * Second, Series: query.Series{Name: "cpu"}, Values: []interface{}{int64(3)}},
},
},
} {
t.Run(test.Name, func(t *testing.T) {
shardMapper := ShardMapper{
Expand Down

0 comments on commit 634471f

Please sign in to comment.