Skip to content

Commit

Permalink
Merge pull request #6621 from influxdata/nc-holt-winters
Browse files Browse the repository at this point in the history
Add a basic Holt-Winters algorithm to the query engine
  • Loading branch information
Nathaniel Cook committed May 19, 2016
2 parents 0f0e9bb + 6ed0d94 commit 393fd5b
Show file tree
Hide file tree
Showing 10 changed files with 1,229 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- [#6664](https://github.com/influxdata/influxdb/pull/6664): Adds monitoring statistic for on-disk shard size.
- [#2926](https://github.com/influxdata/influxdb/issues/2926): Support bound parameters in the parser.
- [#1310](https://github.com/influxdata/influxdb/issues/1310): Add https-private-key option to httpd config.
- [#6621](https://github.com/influxdata/influxdb/pull/6621): Add Holt-Winter forecasting function.

### Bugfixes

Expand Down
23 changes: 23 additions & 0 deletions influxql/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,29 @@ func (s *SelectStatement) validateAggregates(tr targetRequirement) error {
if err := s.validPercentileAggr(expr); err != nil {
return err
}
case "holt_winters", "holt_winters_with_fit":
if exp, got := 3, len(expr.Args); got != exp {
return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", expr.Name, exp, got)
}
// Validate that if they have grouping by time, they need a sub-call like min/max, etc.
groupByInterval, err := s.GroupByInterval()
if err != nil {
return fmt.Errorf("invalid group interval: %v", err)
}

if _, ok := expr.Args[0].(*Call); ok && groupByInterval == 0 {
return fmt.Errorf("%s aggregate requires a GROUP BY interval", expr.Name)
} else if !ok {
return fmt.Errorf("must use aggregate function with %s", expr.Name)
}
if arg, ok := expr.Args[1].(*IntegerLiteral); !ok {
return fmt.Errorf("expected integer argument as second arg in %s", expr.Name)
} else if arg.Val <= 0 {
return fmt.Errorf("second arg to %s must be greater than 0, got %d", expr.Name, arg.Val)
}
if _, ok := expr.Args[2].(*IntegerLiteral); !ok {
return fmt.Errorf("expected integer argument as third arg in %s", expr.Name)
}
default:
if err := s.validSelectWithAggregate(); err != nil {
return err
Expand Down
21 changes: 21 additions & 0 deletions influxql/call_iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"math"
"sort"
"time"
)

/*
Expand Down Expand Up @@ -1058,3 +1059,23 @@ func newMovingAverageIterator(input Iterator, n int, opt IteratorOptions) (Itera
return nil, fmt.Errorf("unsupported moving average iterator type: %T", input)
}
}

// newHoltWintersIterator returns an iterator for operating on a elapsed() call.
func newHoltWintersIterator(input Iterator, opt IteratorOptions, h, m int, includeFitData bool, interval time.Duration) (Iterator, error) {
switch input := input.(type) {
case FloatIterator:
createFn := func() (FloatPointAggregator, FloatPointEmitter) {
fn := NewFloatHoltWintersReducer(h, m, includeFitData, interval)
return fn, fn
}
return &floatReduceFloatIterator{input: newBufFloatIterator(input), opt: opt, create: createFn}, nil
case IntegerIterator:
createFn := func() (IntegerPointAggregator, FloatPointEmitter) {
fn := NewFloatHoltWintersReducer(h, m, includeFitData, interval)
return fn, fn
}
return &integerReduceFloatIterator{input: newBufIntegerIterator(input), opt: opt, create: createFn}, nil
default:
return nil, fmt.Errorf("unsupported elapsed iterator type: %T", input)
}
}
Loading

0 comments on commit 393fd5b

Please sign in to comment.