2018-05-21 21:13:54 +00:00
|
|
|
package functions
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2018-05-21 21:20:06 +00:00
|
|
|
"github.com/influxdata/platform/query"
|
|
|
|
"github.com/influxdata/platform/query/execute"
|
|
|
|
"github.com/influxdata/platform/query/plan"
|
2018-05-21 21:13:54 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const SumKind = "sum"
|
|
|
|
|
|
|
|
type SumOpSpec struct {
|
|
|
|
execute.AggregateConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
var sumSignature = query.DefaultFunctionSignature()
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
query.RegisterFunction(SumKind, createSumOpSpec, sumSignature)
|
|
|
|
query.RegisterOpSpec(SumKind, newSumOp)
|
|
|
|
plan.RegisterProcedureSpec(SumKind, newSumProcedure, SumKind)
|
|
|
|
execute.RegisterTransformation(SumKind, createSumTransformation)
|
|
|
|
}
|
|
|
|
|
|
|
|
func createSumOpSpec(args query.Arguments, a *query.Administration) (query.OperationSpec, error) {
|
|
|
|
if err := a.AddParentFromArgs(args); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
s := new(SumOpSpec)
|
|
|
|
if err := s.AggregateConfig.ReadArgs(args); err != nil {
|
|
|
|
return s, err
|
|
|
|
}
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func newSumOp() query.OperationSpec {
|
|
|
|
return new(SumOpSpec)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SumOpSpec) Kind() query.OperationKind {
|
|
|
|
return SumKind
|
|
|
|
}
|
|
|
|
|
|
|
|
type SumProcedureSpec struct {
|
|
|
|
execute.AggregateConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
func newSumProcedure(qs query.OperationSpec, a plan.Administration) (plan.ProcedureSpec, error) {
|
|
|
|
spec, ok := qs.(*SumOpSpec)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("invalid spec type %T", qs)
|
|
|
|
}
|
|
|
|
return &SumProcedureSpec{
|
|
|
|
AggregateConfig: spec.AggregateConfig,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SumProcedureSpec) Kind() plan.ProcedureKind {
|
|
|
|
return SumKind
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SumProcedureSpec) Copy() plan.ProcedureSpec {
|
|
|
|
return &SumProcedureSpec{
|
|
|
|
AggregateConfig: s.AggregateConfig,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SumProcedureSpec) AggregateMethod() string {
|
|
|
|
return SumKind
|
|
|
|
}
|
|
|
|
func (s *SumProcedureSpec) ReAggregateSpec() plan.ProcedureSpec {
|
|
|
|
return new(SumProcedureSpec)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SumProcedureSpec) PushDownRules() []plan.PushDownRule {
|
|
|
|
return []plan.PushDownRule{{
|
|
|
|
Root: FromKind,
|
|
|
|
Through: nil,
|
|
|
|
Match: func(spec plan.ProcedureSpec) bool {
|
|
|
|
selectSpec := spec.(*FromProcedureSpec)
|
|
|
|
return !selectSpec.GroupingSet
|
|
|
|
},
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
func (s *SumProcedureSpec) PushDown(root *plan.Procedure, dup func() *plan.Procedure) {
|
|
|
|
selectSpec := root.Spec.(*FromProcedureSpec)
|
|
|
|
if selectSpec.AggregateSet {
|
|
|
|
root = dup()
|
|
|
|
selectSpec = root.Spec.(*FromProcedureSpec)
|
|
|
|
selectSpec.AggregateSet = false
|
|
|
|
selectSpec.AggregateMethod = ""
|
|
|
|
return
|
|
|
|
}
|
|
|
|
selectSpec.AggregateSet = true
|
|
|
|
selectSpec.AggregateMethod = s.AggregateMethod()
|
|
|
|
}
|
|
|
|
|
|
|
|
type SumAgg struct{}
|
|
|
|
|
|
|
|
func createSumTransformation(id execute.DatasetID, mode execute.AccumulationMode, spec plan.ProcedureSpec, a execute.Administration) (execute.Transformation, execute.Dataset, error) {
|
|
|
|
s, ok := spec.(*SumProcedureSpec)
|
|
|
|
if !ok {
|
|
|
|
return nil, nil, fmt.Errorf("invalid spec type %T", spec)
|
|
|
|
}
|
|
|
|
|
|
|
|
t, d := execute.NewAggregateTransformationAndDataset(id, mode, new(SumAgg), s.AggregateConfig, a.Allocator())
|
|
|
|
return t, d, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *SumAgg) NewBoolAgg() execute.DoBoolAgg {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func (a *SumAgg) NewIntAgg() execute.DoIntAgg {
|
|
|
|
return new(SumIntAgg)
|
|
|
|
}
|
|
|
|
func (a *SumAgg) NewUIntAgg() execute.DoUIntAgg {
|
|
|
|
return new(SumUIntAgg)
|
|
|
|
}
|
|
|
|
func (a *SumAgg) NewFloatAgg() execute.DoFloatAgg {
|
|
|
|
return new(SumFloatAgg)
|
|
|
|
}
|
|
|
|
func (a *SumAgg) NewStringAgg() execute.DoStringAgg {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type SumIntAgg struct {
|
|
|
|
sum int64
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *SumIntAgg) DoInt(vs []int64) {
|
|
|
|
for _, v := range vs {
|
|
|
|
a.sum += v
|
|
|
|
}
|
|
|
|
}
|
2018-05-21 23:02:42 +00:00
|
|
|
func (a *SumIntAgg) Type() query.DataType {
|
|
|
|
return query.TInt
|
2018-05-21 21:13:54 +00:00
|
|
|
}
|
|
|
|
func (a *SumIntAgg) ValueInt() int64 {
|
|
|
|
return a.sum
|
|
|
|
}
|
|
|
|
|
|
|
|
type SumUIntAgg struct {
|
|
|
|
sum uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *SumUIntAgg) DoUInt(vs []uint64) {
|
|
|
|
for _, v := range vs {
|
|
|
|
a.sum += v
|
|
|
|
}
|
|
|
|
}
|
2018-05-21 23:02:42 +00:00
|
|
|
func (a *SumUIntAgg) Type() query.DataType {
|
|
|
|
return query.TUInt
|
2018-05-21 21:13:54 +00:00
|
|
|
}
|
|
|
|
func (a *SumUIntAgg) ValueUInt() uint64 {
|
|
|
|
return a.sum
|
|
|
|
}
|
|
|
|
|
|
|
|
type SumFloatAgg struct {
|
|
|
|
sum float64
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *SumFloatAgg) DoFloat(vs []float64) {
|
|
|
|
for _, v := range vs {
|
|
|
|
a.sum += v
|
|
|
|
}
|
|
|
|
}
|
2018-05-21 23:02:42 +00:00
|
|
|
func (a *SumFloatAgg) Type() query.DataType {
|
|
|
|
return query.TFloat
|
2018-05-21 21:13:54 +00:00
|
|
|
}
|
|
|
|
func (a *SumFloatAgg) ValueFloat() float64 {
|
|
|
|
return a.sum
|
|
|
|
}
|