Prevent deadlock when doing math on the result of a subquery

The `fill(none)` attribute got set on subqueries, but that can cause an
issue with certain subqueries just like it caused a deadlock on outer
queries.
pull/8864/head
Jonathan A. Sternberg 2017-09-22 09:57:32 -05:00
parent 1e345aa7a1
commit bcf2e8fca5
3 changed files with 56 additions and 6 deletions

View File

@ -58,6 +58,7 @@
- [#8697](https://github.com/influxdata/influxdb/issues/8697): Drop Series Cause Write Fail/Write Timeouts/High Memory Usage
- [#8741](https://github.com/influxdata/influxdb/issues/8741): Fix increased memory usage in cache and wal readers
- [#8678](https://github.com/influxdata/influxdb/issues/8678): Ensure time and tag-based condition can be used with tsi1 index when deleting.
- [#8848](https://github.com/influxdata/influxdb/issues/8848): Prevent deadlock when doing math on the result of a subquery.
## v1.3.4 [unreleased]

View File

@ -837,12 +837,15 @@ func newIteratorOptionsSubstatement(stmt *influxql.SelectStatement, opt Iterator
// Propagate the ordering from the parent query.
subOpt.Ascending = opt.Ascending
// If the inner query uses a null fill option, switch it to none so we
// don't hit an unnecessary penalty from the fill iterator. Null values
// will end up getting stripped by an outer query anyway so there's no
// point in having them here. We still need all other types of fill
// iterators because they can affect the result of the outer query.
if subOpt.Fill == influxql.NullFill {
// If the inner query uses a null fill option and is not a raw query,
// switch it to none so we don't hit an unnecessary penalty from the
// fill iterator. Null values will end up getting stripped by an outer
// query anyway so there's no point in having them here. We still need
// all other types of fill iterators because they can affect the result
// of the outer query. We also do not do this for raw queries because
// there is no fill iterator for them and fill(none) doesn't work with
// raw queries.
if !stmt.IsRawQuery && subOpt.Fill == influxql.NullFill {
subOpt.Fill = influxql.NoFill
}

View File

@ -5459,6 +5459,52 @@ func TestServer_Query_SubqueryWithGroupBy(t *testing.T) {
}
}
func TestServer_Query_SubqueryMath(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("m0 f2=4,f3=2 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()),
fmt.Sprintf("m0 f1=5,f3=8 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()),
fmt.Sprintf("m0 f1=5,f2=3,f3=6 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()),
}
test := NewTest("db0", "rp0")
test.writes = Writes{
&Write{data: strings.Join(writes, "\n")},
}
test.addQueries([]*Query{
&Query{
name: "SumThreeValues",
params: url.Values{"db": []string{"db0"}},
command: `SELECT sum FROM (SELECT f1 + f2 + f3 AS sum FROM m0)`,
exp: `{"results":[{"statement_id":0,"series":[{"name":"m0","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",null],["2000-01-01T00:00:10Z",null],["2000-01-01T00:00:20Z",14]]}]}]}`,
},
}...)
if err := test.init(s); err != nil {
t.Fatalf("test init failed: %s", err)
}
for _, query := range test.queries {
t.Run(query.name, func(t *testing.T) {
if query.skip {
t.Skipf("SKIP:: %s", query.name)
}
if err := query.Execute(s); err != nil {
t.Error(query.Error(err))
} else if !query.success() {
t.Error(query.failureMessage())
}
})
}
}
func TestServer_Query_PercentileDerivative(t *testing.T) {
t.Parallel()
s := OpenServer(NewConfig())