func FloatFirstReduce(prev, curr *FloatPoint) (int64, float64, []interface{}) {
	if prev == nil || curr.Time < prev.Time || (curr.Time == prev.Time && curr.Value > prev.Value) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
FloatFirstReduce returns the first point sorted by time.
package query
import (
	"fmt"
	"math"
	"sort"
	"time"
	"github.com/influxdata/influxql"
)
func NewCallIterator(input Iterator, opt IteratorOptions) (Iterator, error) {
	name := opt.Expr.(*influxql.Call).Name
	switch name {
	case "count":
		return newCountIterator(input, opt)
	case "min":
		return newMinIterator(input, opt)
	case "max":
		return newMaxIterator(input, opt)
	case "sum":
		return newSumIterator(input, opt)
	case "first":
		return newFirstIterator(input, opt)
	case "last":
		return newLastIterator(input, opt)
	case "mean":
		return newMeanIterator(input, opt)
	default:
		return nil, fmt.Errorf("unsupported function call: %s", name)
	}
}
func newCountIterator(input Iterator, opt IteratorOptions) (Iterator, error) {
	switch input := input.(type) {
	case FloatIterator:
		createFn := func() (FloatPointAggregator, IntegerPointEmitter) {
			fn := NewFloatFuncIntegerReducer(FloatCountReduce, &IntegerPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newFloatReduceIntegerIterator(input, opt, createFn), nil
	case IntegerIterator:
		createFn := func() (IntegerPointAggregator, IntegerPointEmitter) {
			fn := NewIntegerFuncReducer(IntegerCountReduce, &IntegerPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newIntegerReduceIntegerIterator(input, opt, createFn), nil
	case UnsignedIterator:
		createFn := func() (UnsignedPointAggregator, IntegerPointEmitter) {
			fn := NewUnsignedFuncIntegerReducer(UnsignedCountReduce, &IntegerPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newUnsignedReduceIntegerIterator(input, opt, createFn), nil
	case StringIterator:
		createFn := func() (StringPointAggregator, IntegerPointEmitter) {
			fn := NewStringFuncIntegerReducer(StringCountReduce, &IntegerPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newStringReduceIntegerIterator(input, opt, createFn), nil
	case BooleanIterator:
		createFn := func() (BooleanPointAggregator, IntegerPointEmitter) {
			fn := NewBooleanFuncIntegerReducer(BooleanCountReduce, &IntegerPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newBooleanReduceIntegerIterator(input, opt, createFn), nil
	default:
		return nil, fmt.Errorf("unsupported count iterator type: %T", input)
	}
}
func FloatCountReduce(prev *IntegerPoint, curr *FloatPoint) (int64, int64, []interface{}) {
	if prev == nil {
		return ZeroTime, 1, nil
	}
	return ZeroTime, prev.Value + 1, nil
}
func IntegerCountReduce(prev, curr *IntegerPoint) (int64, int64, []interface{}) {
	if prev == nil {
		return ZeroTime, 1, nil
	}
	return ZeroTime, prev.Value + 1, nil
}
func UnsignedCountReduce(prev *IntegerPoint, curr *UnsignedPoint) (int64, int64, []interface{}) {
	if prev == nil {
		return ZeroTime, 1, nil
	}
	return ZeroTime, prev.Value + 1, nil
}
func StringCountReduce(prev *IntegerPoint, curr *StringPoint) (int64, int64, []interface{}) {
	if prev == nil {
		return ZeroTime, 1, nil
	}
	return ZeroTime, prev.Value + 1, nil
}
func BooleanCountReduce(prev *IntegerPoint, curr *BooleanPoint) (int64, int64, []interface{}) {
	if prev == nil {
		return ZeroTime, 1, nil
	}
	return ZeroTime, prev.Value + 1, nil
}
func newMinIterator(input Iterator, opt IteratorOptions) (Iterator, error) {
	switch input := input.(type) {
	case FloatIterator:
		createFn := func() (FloatPointAggregator, FloatPointEmitter) {
			fn := NewFloatFuncReducer(FloatMinReduce, nil)
			return fn, fn
		}
		return newFloatReduceFloatIterator(input, opt, createFn), nil
	case IntegerIterator:
		createFn := func() (IntegerPointAggregator, IntegerPointEmitter) {
			fn := NewIntegerFuncReducer(IntegerMinReduce, nil)
			return fn, fn
		}
		return newIntegerReduceIntegerIterator(input, opt, createFn), nil
	case UnsignedIterator:
		createFn := func() (UnsignedPointAggregator, UnsignedPointEmitter) {
			fn := NewUnsignedFuncReducer(UnsignedMinReduce, nil)
			return fn, fn
		}
		return newUnsignedReduceUnsignedIterator(input, opt, createFn), nil
	case BooleanIterator:
		createFn := func() (BooleanPointAggregator, BooleanPointEmitter) {
			fn := NewBooleanFuncReducer(BooleanMinReduce, nil)
			return fn, fn
		}
		return newBooleanReduceBooleanIterator(input, opt, createFn), nil
	default:
		return nil, fmt.Errorf("unsupported min iterator type: %T", input)
	}
}
func FloatMinReduce(prev, curr *FloatPoint) (int64, float64, []interface{}) {
	if prev == nil || curr.Value < prev.Value || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func IntegerMinReduce(prev, curr *IntegerPoint) (int64, int64, []interface{}) {
	if prev == nil || curr.Value < prev.Value || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func UnsignedMinReduce(prev, curr *UnsignedPoint) (int64, uint64, []interface{}) {
	if prev == nil || curr.Value < prev.Value || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func BooleanMinReduce(prev, curr *BooleanPoint) (int64, bool, []interface{}) {
	if prev == nil || (curr.Value != prev.Value && !curr.Value) || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func newMaxIterator(input Iterator, opt IteratorOptions) (Iterator, error) {
	switch input := input.(type) {
	case FloatIterator:
		createFn := func() (FloatPointAggregator, FloatPointEmitter) {
			fn := NewFloatFuncReducer(FloatMaxReduce, nil)
			return fn, fn
		}
		return newFloatReduceFloatIterator(input, opt, createFn), nil
	case IntegerIterator:
		createFn := func() (IntegerPointAggregator, IntegerPointEmitter) {
			fn := NewIntegerFuncReducer(IntegerMaxReduce, nil)
			return fn, fn
		}
		return newIntegerReduceIntegerIterator(input, opt, createFn), nil
	case UnsignedIterator:
		createFn := func() (UnsignedPointAggregator, UnsignedPointEmitter) {
			fn := NewUnsignedFuncReducer(UnsignedMaxReduce, nil)
			return fn, fn
		}
		return newUnsignedReduceUnsignedIterator(input, opt, createFn), nil
	case BooleanIterator:
		createFn := func() (BooleanPointAggregator, BooleanPointEmitter) {
			fn := NewBooleanFuncReducer(BooleanMaxReduce, nil)
			return fn, fn
		}
		return newBooleanReduceBooleanIterator(input, opt, createFn), nil
	default:
		return nil, fmt.Errorf("unsupported max iterator type: %T", input)
	}
}
func FloatMaxReduce(prev, curr *FloatPoint) (int64, float64, []interface{}) {
	if prev == nil || curr.Value > prev.Value || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func IntegerMaxReduce(prev, curr *IntegerPoint) (int64, int64, []interface{}) {
	if prev == nil || curr.Value > prev.Value || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func UnsignedMaxReduce(prev, curr *UnsignedPoint) (int64, uint64, []interface{}) {
	if prev == nil || curr.Value > prev.Value || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func BooleanMaxReduce(prev, curr *BooleanPoint) (int64, bool, []interface{}) {
	if prev == nil || (curr.Value != prev.Value && curr.Value) || (curr.Value == prev.Value && curr.Time < prev.Time) {
		return curr.Time, curr.Value, cloneAux(curr.Aux)
	}
	return prev.Time, prev.Value, prev.Aux
}
func newSumIterator(input Iterator, opt IteratorOptions) (Iterator, error) {
	switch input := input.(type) {
	case FloatIterator:
		createFn := func() (FloatPointAggregator, FloatPointEmitter) {
			fn := NewFloatFuncReducer(FloatSumReduce, &FloatPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newFloatReduceFloatIterator(input, opt, createFn), nil
	case IntegerIterator:
		createFn := func() (IntegerPointAggregator, IntegerPointEmitter) {
			fn := NewIntegerFuncReducer(IntegerSumReduce, &IntegerPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newIntegerReduceIntegerIterator(input, opt, createFn), nil
	case UnsignedIterator:
		createFn := func() (UnsignedPointAggregator, UnsignedPointEmitter) {
			fn := NewUnsignedFuncReducer(UnsignedSumReduce, &UnsignedPoint{Value: 0, Time: ZeroTime})
			return fn, fn
		}
		return newUnsignedReduceUnsignedIterator(input, opt, createFn), nil
	default:
		return nil, fmt.Errorf("unsupported sum iterator type: %T", input)
	}
}
func FloatSumReduce(prev, curr *FloatPoint) (int64, float64, []interface{}) {
	if prev == nil {
		return ZeroTime, curr.Value, nil
	}
	return prev.Time, prev.Value + curr.Value, nil
}
func IntegerSumReduce(prev, curr *IntegerPoint) (int64, int64, []interface{}) {
	if prev == nil {
		return ZeroTime, curr.Value, nil
	}
	return prev.Time, prev.Value + curr.Value, nil
}
func UnsignedSumReduce(prev, curr *UnsignedPoint) (int64, uint64, []interface{}) {
	if prev == nil {
		return ZeroTime, curr.Value, nil
	}
	return prev.Time, prev.Value + curr.Value, nil
}
func newFirstIterator(input Iterator, opt IteratorOptions) (Iterator, error) {
	switch input := input.(type) {
	case FloatIterator:
		createFn := func() (FloatPointAggregator, FloatPointEmitter) {
			fn := NewFloatFuncReducer(FloatFirstReduce, nil)
			return fn, fn
		}
		return newFloatReduceFloatIterator(input, opt, createFn), nil
	case IntegerIterator:
		createFn := func() (IntegerPointAggregator, IntegerPointEmitter) {
			fn := NewIntegerFuncReducer(IntegerFirstReduce, nil)
			return fn, fn
		}
		return newIntegerReduceIntegerIterator(input, opt, createFn), nil
	case UnsignedIterator:
		createFn := func() (UnsignedPointAggregator, UnsignedPointEmitter) {
			fn := NewUnsignedFuncReducer(UnsignedFirstReduce, nil)
			return fn, fn
		}
		return newUnsignedReduceUnsignedIterator(input, opt, createFn), nil
	case StringIterator:
		createFn := func() (StringPointAggregator, StringPointEmitter) {
			fn := NewStringFuncReducer(StringFirstReduce, nil)
			return fn, fn
		}
		return newStringReduceStringIterator(input, opt, createFn), nil
	case BooleanIterator:
		createFn := func() (BooleanPointAggregator, BooleanPointEmitter) {
			fn := NewBooleanFuncReducer(BooleanFirstReduce, nil)
			return fn, fn
		}
		return newBooleanReduceBooleanIterator(input, opt, createFn), nil
	default:
		return nil, fmt.Errorf("unsupported first iterator type: %T", input)
	}
}