2019-04-04 15:55:09 +00:00
|
|
|
package reads
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
2021-03-31 17:51:37 +00:00
|
|
|
"github.com/influxdata/flux/interval"
|
2019-04-04 15:55:09 +00:00
|
|
|
"github.com/influxdata/influxdb/storage/reads/datatypes"
|
|
|
|
"github.com/influxdata/influxdb/tsdb/cursors"
|
|
|
|
)
|
|
|
|
|
|
|
|
type singleValue struct {
|
|
|
|
v interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *singleValue) Value(key string) (interface{}, bool) {
|
|
|
|
return v.v, true
|
|
|
|
}
|
|
|
|
|
2021-04-29 18:30:13 +00:00
|
|
|
func newAggregateArrayCursor(ctx context.Context, agg []*datatypes.Aggregate, cursor cursors.Cursor) (cursors.Cursor, error) {
|
|
|
|
switch agg[0].Type {
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeFirst, datatypes.Aggregate_AggregateTypeLast:
|
2021-03-31 17:51:37 +00:00
|
|
|
return newLimitArrayCursor(cursor), nil
|
|
|
|
}
|
2021-04-27 20:18:59 +00:00
|
|
|
return NewWindowAggregateArrayCursor(ctx, agg, interval.Window{}, cursor)
|
2021-03-31 17:51:37 +00:00
|
|
|
}
|
|
|
|
|
2021-04-29 18:30:13 +00:00
|
|
|
func NewWindowAggregateArrayCursor(ctx context.Context, agg []*datatypes.Aggregate, window interval.Window, cursor cursors.Cursor) (cursors.Cursor, error) {
|
2019-04-04 15:55:09 +00:00
|
|
|
if cursor == nil {
|
2021-03-31 17:51:37 +00:00
|
|
|
return nil, nil
|
2019-04-04 15:55:09 +00:00
|
|
|
}
|
|
|
|
|
2021-04-29 18:30:13 +00:00
|
|
|
switch agg[0].Type {
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeCount:
|
2021-03-31 17:51:37 +00:00
|
|
|
return newWindowCountArrayCursor(cursor, window), nil
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeSum:
|
2021-03-31 17:51:37 +00:00
|
|
|
return newWindowSumArrayCursor(cursor, window)
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeFirst:
|
2021-03-31 17:51:37 +00:00
|
|
|
return newWindowFirstArrayCursor(cursor, window), nil
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeLast:
|
2021-03-31 17:51:37 +00:00
|
|
|
return newWindowLastArrayCursor(cursor, window), nil
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeMin:
|
2021-03-31 17:51:37 +00:00
|
|
|
return newWindowMinArrayCursor(cursor, window), nil
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeMax:
|
2021-03-31 17:51:37 +00:00
|
|
|
return newWindowMaxArrayCursor(cursor, window), nil
|
2021-10-15 16:42:47 +00:00
|
|
|
case datatypes.Aggregate_AggregateTypeMean:
|
|
|
|
if len(agg) == 2 && agg[1].Type == datatypes.Aggregate_AggregateTypeCount {
|
2021-04-29 18:30:13 +00:00
|
|
|
return newWindowMeanCountArrayCursor(cursor, window)
|
|
|
|
}
|
2021-03-31 17:51:37 +00:00
|
|
|
return newWindowMeanArrayCursor(cursor, window)
|
2021-04-29 18:30:13 +00:00
|
|
|
|
2019-04-04 15:55:09 +00:00
|
|
|
default:
|
|
|
|
// TODO(sgc): should be validated higher up
|
|
|
|
panic("invalid aggregate")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type cursorContext struct {
|
2021-03-31 17:51:37 +00:00
|
|
|
ctx context.Context
|
|
|
|
req *cursors.CursorRequest
|
|
|
|
itrs cursors.CursorIterators
|
|
|
|
err error
|
2019-04-04 15:55:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type multiShardArrayCursors struct {
|
2021-03-31 17:51:37 +00:00
|
|
|
ctx context.Context
|
|
|
|
req cursors.CursorRequest
|
2019-04-04 15:55:09 +00:00
|
|
|
|
|
|
|
cursors struct {
|
|
|
|
i integerMultiShardArrayCursor
|
|
|
|
f floatMultiShardArrayCursor
|
|
|
|
u unsignedMultiShardArrayCursor
|
|
|
|
b booleanMultiShardArrayCursor
|
|
|
|
s stringMultiShardArrayCursor
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
fix(storage): cursor requests are [start, stop] instead of [start, stop) (#21347)
* fix: backport tsdb fix for window pushdowns
From https://github.com/influxdata/influxdb/pull/19855
* fix(storage): cursor requests are [start, stop] instead of [start, stop)
The cursors were previously [start, stop) to be consistent with how flux
requests data, but the underlying storage file store was [start, stop]
because that's how influxql read data. This reverts back the cursor
behavior so that it is now [start, stop] everywhere and the conversion
from [start, stop) to [start, stop] is performed when doing the cursor
request to get the next cursor.
cherry-pick from #21318
Co-authored-by: Sam Arnold <sarnold@influxdata.com>
(cherry picked from commit 776667279733519972dbc27fe559c1d8ffd5864a)
* chore: fix formatting
Co-authored-by: Jonathan A. Sternberg <jonathan@influxdata.com>
2021-04-30 19:26:31 +00:00
|
|
|
// newMultiShardArrayCursors is a factory for creating cursors for each series key.
|
|
|
|
// The range of the cursor is [start, end). The start time is the lower absolute time
|
|
|
|
// and the end time is the higher absolute time regardless of ascending or descending order.
|
2021-03-31 17:51:37 +00:00
|
|
|
func newMultiShardArrayCursors(ctx context.Context, start, end int64, asc bool) *multiShardArrayCursors {
|
fix(storage): cursor requests are [start, stop] instead of [start, stop) (#21347)
* fix: backport tsdb fix for window pushdowns
From https://github.com/influxdata/influxdb/pull/19855
* fix(storage): cursor requests are [start, stop] instead of [start, stop)
The cursors were previously [start, stop) to be consistent with how flux
requests data, but the underlying storage file store was [start, stop]
because that's how influxql read data. This reverts back the cursor
behavior so that it is now [start, stop] everywhere and the conversion
from [start, stop) to [start, stop] is performed when doing the cursor
request to get the next cursor.
cherry-pick from #21318
Co-authored-by: Sam Arnold <sarnold@influxdata.com>
(cherry picked from commit 776667279733519972dbc27fe559c1d8ffd5864a)
* chore: fix formatting
Co-authored-by: Jonathan A. Sternberg <jonathan@influxdata.com>
2021-04-30 19:26:31 +00:00
|
|
|
// When we construct the CursorRequest, we translate the time range
|
|
|
|
// from [start, stop) to [start, stop]. The cursor readers from storage are
|
|
|
|
// inclusive on both ends and we perform that conversion here.
|
2019-04-04 15:55:09 +00:00
|
|
|
m := &multiShardArrayCursors{
|
2021-03-31 17:51:37 +00:00
|
|
|
ctx: ctx,
|
2019-04-04 15:55:09 +00:00
|
|
|
req: cursors.CursorRequest{
|
|
|
|
Ascending: asc,
|
|
|
|
StartTime: start,
|
fix(storage): cursor requests are [start, stop] instead of [start, stop) (#21347)
* fix: backport tsdb fix for window pushdowns
From https://github.com/influxdata/influxdb/pull/19855
* fix(storage): cursor requests are [start, stop] instead of [start, stop)
The cursors were previously [start, stop) to be consistent with how flux
requests data, but the underlying storage file store was [start, stop]
because that's how influxql read data. This reverts back the cursor
behavior so that it is now [start, stop] everywhere and the conversion
from [start, stop) to [start, stop] is performed when doing the cursor
request to get the next cursor.
cherry-pick from #21318
Co-authored-by: Sam Arnold <sarnold@influxdata.com>
(cherry picked from commit 776667279733519972dbc27fe559c1d8ffd5864a)
* chore: fix formatting
Co-authored-by: Jonathan A. Sternberg <jonathan@influxdata.com>
2021-04-30 19:26:31 +00:00
|
|
|
EndTime: end - 1,
|
2019-04-04 15:55:09 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
cc := cursorContext{
|
2021-03-31 17:51:37 +00:00
|
|
|
ctx: ctx,
|
|
|
|
req: &m.req,
|
2019-04-04 15:55:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
m.cursors.i.cursorContext = cc
|
|
|
|
m.cursors.f.cursorContext = cc
|
|
|
|
m.cursors.u.cursorContext = cc
|
|
|
|
m.cursors.b.cursorContext = cc
|
|
|
|
m.cursors.s.cursorContext = cc
|
|
|
|
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *multiShardArrayCursors) createCursor(row SeriesRow) cursors.Cursor {
|
|
|
|
m.req.Name = row.Name
|
|
|
|
m.req.Tags = row.SeriesTags
|
|
|
|
m.req.Field = row.Field
|
|
|
|
|
|
|
|
var cond expression
|
|
|
|
if row.ValueCond != nil {
|
|
|
|
cond = &astExpr{row.ValueCond}
|
|
|
|
}
|
|
|
|
|
|
|
|
var shard cursors.CursorIterator
|
|
|
|
var cur cursors.Cursor
|
|
|
|
for cur == nil && len(row.Query) > 0 {
|
|
|
|
shard, row.Query = row.Query[0], row.Query[1:]
|
|
|
|
cur, _ = shard.Next(m.ctx, &m.req)
|
|
|
|
}
|
|
|
|
|
|
|
|
if cur == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
switch c := cur.(type) {
|
|
|
|
case cursors.IntegerArrayCursor:
|
|
|
|
m.cursors.i.reset(c, row.Query, cond)
|
|
|
|
return &m.cursors.i
|
|
|
|
case cursors.FloatArrayCursor:
|
|
|
|
m.cursors.f.reset(c, row.Query, cond)
|
|
|
|
return &m.cursors.f
|
|
|
|
case cursors.UnsignedArrayCursor:
|
|
|
|
m.cursors.u.reset(c, row.Query, cond)
|
|
|
|
return &m.cursors.u
|
|
|
|
case cursors.StringArrayCursor:
|
|
|
|
m.cursors.s.reset(c, row.Query, cond)
|
|
|
|
return &m.cursors.s
|
|
|
|
case cursors.BooleanArrayCursor:
|
|
|
|
m.cursors.b.reset(c, row.Query, cond)
|
|
|
|
return &m.cursors.b
|
|
|
|
default:
|
|
|
|
panic(fmt.Sprintf("unreachable: %T", cur))
|
|
|
|
}
|
|
|
|
}
|