| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991 |
- // Copyright 2014 The ql Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package ql
- import (
- "fmt"
- "math/rand"
- "reflect"
- "strconv"
- "strings"
- "time"
- )
- //TODO agg bigint, bigrat, time, duration
- var builtin = map[string]struct {
- f func([]interface{}, map[interface{}]interface{}) (interface{}, error)
- minArgs int
- maxArgs int
- isStatic bool
- isAggregate bool
- }{
- "__testBlob": {builtinTestBlob, 1, 1, true, false},
- "__testString": {builtinTestString, 1, 1, true, false},
- "avg": {builtinAvg, 1, 1, false, true},
- "complex": {builtinComplex, 2, 2, true, false},
- "contains": {builtinContains, 2, 2, true, false},
- "count": {builtinCount, 0, 1, false, true},
- "date": {builtinDate, 8, 8, true, false},
- "day": {builtinDay, 1, 1, true, false},
- "formatTime": {builtinFormatTime, 2, 2, true, false},
- "formatFloat": {builtinFormatFloat, 1, 4, true, false},
- "formatInt": {builtinFormatInt, 1, 2, true, false},
- "hasPrefix": {builtinHasPrefix, 2, 2, true, false},
- "hasSuffix": {builtinHasSuffix, 2, 2, true, false},
- "hour": {builtinHour, 1, 1, true, false},
- "hours": {builtinHours, 1, 1, true, false},
- "id": {builtinID, 0, 1, false, false},
- "imag": {builtinImag, 1, 1, true, false},
- "len": {builtinLen, 1, 1, true, false},
- "max": {builtinMax, 1, 1, false, true},
- "min": {builtinMin, 1, 1, false, true},
- "minute": {builtinMinute, 1, 1, true, false},
- "minutes": {builtinMinutes, 1, 1, true, false},
- "month": {builtinMonth, 1, 1, true, false},
- "nanosecond": {builtinNanosecond, 1, 1, true, false},
- "nanoseconds": {builtinNanoseconds, 1, 1, true, false},
- "now": {builtinNow, 0, 0, false, false},
- "parseTime": {builtinParseTime, 2, 2, true, false},
- "real": {builtinReal, 1, 1, true, false},
- "second": {builtinSecond, 1, 1, true, false},
- "seconds": {builtinSeconds, 1, 1, true, false},
- "since": {builtinSince, 1, 1, false, false},
- "sum": {builtinSum, 1, 1, false, true},
- "timeIn": {builtinTimeIn, 2, 2, true, false},
- "weekday": {builtinWeekday, 1, 1, true, false},
- "year": {builtinYear, 1, 1, true, false},
- "yearDay": {builtinYearday, 1, 1, true, false},
- }
- func badNArgs(min int, s string, arg []interface{}) error {
- a := []string{}
- for _, v := range arg {
- a = append(a, fmt.Sprintf("%v", v))
- }
- switch len(arg) < min {
- case true:
- return fmt.Errorf("missing argument to %s(%s)", s, strings.Join(a, ", "))
- default: //case false:
- return fmt.Errorf("too many arguments to %s(%s)", s, strings.Join(a, ", "))
- }
- }
- func invArg(arg interface{}, s string) error {
- return fmt.Errorf("invalid argument %v (type %T) for %s", arg, arg, s)
- }
- func builtinTestBlob(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- n, err := intExpr(arg[0])
- if err != nil {
- return nil, err
- }
- rng := rand.New(rand.NewSource(n))
- b := make([]byte, n)
- for i := range b {
- b[i] = byte(rng.Int())
- }
- return b, nil
- }
- func builtinTestString(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- n, err := intExpr(arg[0])
- if err != nil {
- return nil, err
- }
- rng := rand.New(rand.NewSource(n))
- b := make([]byte, n)
- for i := range b {
- b[i] = byte(rng.Int())
- }
- return string(b), nil
- }
- func builtinAvg(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- type avg struct {
- sum interface{}
- n uint64
- }
- if _, ok := ctx["$agg0"]; ok {
- return
- }
- fn := ctx["$fn"]
- if _, ok := ctx["$agg"]; ok {
- data, ok := ctx[fn].(avg)
- if !ok {
- return
- }
- switch x := data.sum.(type) {
- case complex64:
- return complex64(complex128(x) / complex(float64(data.n), 0)), nil
- case complex128:
- return complex64(x / complex(float64(data.n), 0)), nil
- case float32:
- return float32(float64(x) / float64(data.n)), nil
- case float64:
- return x / float64(data.n), nil
- case int8:
- return int8(int64(x) / int64(data.n)), nil
- case int16:
- return int16(int64(x) / int64(data.n)), nil
- case int32:
- return int32(int64(x) / int64(data.n)), nil
- case int64:
- return x / int64(data.n), nil
- case uint8:
- return uint8(uint64(x) / data.n), nil
- case uint16:
- return uint16(uint64(x) / data.n), nil
- case uint32:
- return uint32(uint64(x) / data.n), nil
- case uint64:
- return x / data.n, nil
- }
- }
- data, _ := ctx[fn].(avg)
- y := arg[0]
- if y == nil {
- return
- }
- switch x := data.sum.(type) {
- case nil:
- switch y := y.(type) {
- case float32, float64, int8, int16, int32, int64, uint8, uint16, uint32, uint64:
- data = avg{y, 0}
- default:
- return nil, fmt.Errorf("avg: cannot accept %v (value if type %T)", y, y)
- }
- case complex64:
- data.sum = x + y.(complex64)
- case complex128:
- data.sum = x + y.(complex128)
- case float32:
- data.sum = x + y.(float32)
- case float64:
- data.sum = x + y.(float64)
- case int8:
- data.sum = x + y.(int8)
- case int16:
- data.sum = x + y.(int16)
- case int32:
- data.sum = x + y.(int32)
- case int64:
- data.sum = x + y.(int64)
- case uint8:
- data.sum = x + y.(uint8)
- case uint16:
- data.sum = x + y.(uint16)
- case uint32:
- data.sum = x + y.(uint32)
- case uint64:
- data.sum = x + y.(uint64)
- }
- data.n++
- ctx[fn] = data
- return
- }
- func builtinComplex(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- re, im := arg[0], arg[1]
- if re == nil || im == nil {
- return nil, nil
- }
- re, im = coerce(re, im)
- if reflect.TypeOf(re) != reflect.TypeOf(im) {
- return nil, fmt.Errorf("complex(%T(%#v), %T(%#v)): invalid types", re, re, im, im)
- }
- switch re := re.(type) {
- case idealFloat:
- return idealComplex(complex(float64(re), float64(im.(idealFloat)))), nil
- case idealInt:
- return idealComplex(complex(float64(re), float64(im.(idealInt)))), nil
- case idealRune:
- return idealComplex(complex(float64(re), float64(im.(idealRune)))), nil
- case idealUint:
- return idealComplex(complex(float64(re), float64(im.(idealUint)))), nil
- case float32:
- return complex(re, im.(float32)), nil
- case float64:
- return complex(re, im.(float64)), nil
- case int8:
- return complex(float64(re), float64(im.(int8))), nil
- case int16:
- return complex(float64(re), float64(im.(int16))), nil
- case int32:
- return complex(float64(re), float64(im.(int32))), nil
- case int64:
- return complex(float64(re), float64(im.(int64))), nil
- case uint8:
- return complex(float64(re), float64(im.(uint8))), nil
- case uint16:
- return complex(float64(re), float64(im.(uint16))), nil
- case uint32:
- return complex(float64(re), float64(im.(uint32))), nil
- case uint64:
- return complex(float64(re), float64(im.(uint64))), nil
- default:
- return nil, invArg(re, "complex")
- }
- }
- func builtinContains(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- switch s := arg[0].(type) {
- case nil:
- return nil, nil
- case string:
- switch chars := arg[1].(type) {
- case nil:
- return nil, nil
- case string:
- return strings.Contains(s, chars), nil
- default:
- return nil, invArg(chars, "string")
- }
- default:
- return nil, invArg(s, "string")
- }
- }
- func builtinCount(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- if _, ok := ctx["$agg0"]; ok {
- return int64(0), nil
- }
- fn := ctx["$fn"]
- if _, ok := ctx["$agg"]; ok {
- return ctx[fn].(int64), nil
- }
- n, _ := ctx[fn].(int64)
- switch len(arg) {
- case 0:
- n++
- case 1:
- if arg[0] != nil {
- n++
- }
- default:
- panic("internal error 067")
- }
- ctx[fn] = n
- return
- }
- func builtinDate(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- for i, v := range arg {
- switch i {
- case 7:
- switch x := v.(type) {
- case string:
- default:
- return nil, invArg(x, "date")
- }
- default:
- switch x := v.(type) {
- case int64:
- case idealInt:
- arg[i] = int64(x)
- default:
- return nil, invArg(x, "date")
- }
- }
- }
- sloc := arg[7].(string)
- loc := time.Local
- switch sloc {
- case "local":
- default:
- loc, err = time.LoadLocation(sloc)
- if err != nil {
- return
- }
- }
- return time.Date(
- int(arg[0].(int64)),
- time.Month(arg[1].(int64)),
- int(arg[2].(int64)),
- int(arg[3].(int64)),
- int(arg[4].(int64)),
- int(arg[5].(int64)),
- int(arg[6].(int64)),
- loc,
- ), nil
- }
- func builtinLen(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case string:
- return int64(len(x)), nil
- default:
- return nil, invArg(x, "len")
- }
- }
- func builtinDay(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Day()), nil
- default:
- return nil, invArg(x, "day")
- }
- }
- func builtinFormatTime(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- switch y := arg[1].(type) {
- case nil:
- return nil, nil
- case string:
- return x.Format(y), nil
- default:
- return nil, invArg(y, "formatTime")
- }
- default:
- return nil, invArg(x, "formatTime")
- }
- }
- func builtinFormatFloat(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- var val float64
- var fmt byte = 'g'
- prec := -1
- bitSize := 64
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case float32:
- val = float64(x)
- bitSize = 32
- case float64:
- val = x
- default:
- return nil, invArg(x, "formatFloat")
- }
- switch len(arg) {
- case 4:
- arg3 := coerce1(arg[3], int64(0))
- switch y := arg3.(type) {
- case nil:
- return nil, nil
- case int64:
- bitSize = int(y)
- default:
- return nil, invArg(y, "formatFloat")
- }
- fallthrough
- case 3:
- arg2 := coerce1(arg[2], int64(0))
- switch y := arg2.(type) {
- case nil:
- return nil, nil
- case int64:
- prec = int(y)
- default:
- return nil, invArg(y, "formatFloat")
- }
- fallthrough
- case 2:
- arg1 := coerce1(arg[1], byte(0))
- switch y := arg1.(type) {
- case nil:
- return nil, nil
- case byte:
- fmt = y
- default:
- return nil, invArg(y, "formatFloat")
- }
- }
- return strconv.FormatFloat(val, fmt, prec, bitSize), nil
- }
- func builtinFormatInt(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- var intVal int64
- var uintVal uint64
- uintType := false
- base := 10
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case int8:
- intVal = int64(x)
- case int16:
- intVal = int64(x)
- case int32:
- intVal = int64(x)
- case int64:
- intVal = x
- case uint8:
- uintType = true
- uintVal = uint64(x)
- case uint16:
- uintType = true
- uintVal = uint64(x)
- case uint32:
- uintType = true
- uintVal = uint64(x)
- case uint64:
- uintType = true
- uintVal = x
- default:
- return nil, invArg(x, "formatInt")
- }
- switch len(arg) {
- case 2:
- arg1 := coerce1(arg[1], int64(0))
- switch y := arg1.(type) {
- case nil:
- return nil, nil
- case int64:
- base = int(y)
- default:
- return nil, invArg(y, "formatInt")
- }
- }
- if uintType {
- return strconv.FormatUint(uintVal, base), nil
- }
- return strconv.FormatInt(intVal, base), nil
- }
- func builtinHasPrefix(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- switch s := arg[0].(type) {
- case nil:
- return nil, nil
- case string:
- switch prefix := arg[1].(type) {
- case nil:
- return nil, nil
- case string:
- return strings.HasPrefix(s, prefix), nil
- default:
- return nil, invArg(prefix, "string")
- }
- default:
- return nil, invArg(s, "string")
- }
- }
- func builtinHasSuffix(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- switch s := arg[0].(type) {
- case nil:
- return nil, nil
- case string:
- switch suffix := arg[1].(type) {
- case nil:
- return nil, nil
- case string:
- return strings.HasSuffix(s, suffix), nil
- default:
- return nil, invArg(suffix, "string")
- }
- default:
- return nil, invArg(s, "string")
- }
- }
- func builtinHour(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Hour()), nil
- default:
- return nil, invArg(x, "hour")
- }
- }
- func builtinHours(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Duration:
- return x.Hours(), nil
- default:
- return nil, invArg(x, "hours")
- }
- }
- func builtinID(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := ctx["$id"].(type) {
- case map[string]interface{}:
- if len(arg) == 0 {
- return nil, nil
- }
- tab := arg[0].(*ident)
- id, ok := x[tab.s]
- if !ok {
- return nil, fmt.Errorf("value not available: id(%s)", tab)
- }
- if _, ok := id.(int64); ok {
- return id, nil
- }
- return nil, fmt.Errorf("value not available: id(%s)", tab)
- case int64:
- return x, nil
- default:
- return nil, nil
- }
- }
- func builtinImag(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case idealComplex:
- return imag(x), nil
- case complex64:
- return imag(x), nil
- case complex128:
- return imag(x), nil
- default:
- return nil, invArg(x, "imag")
- }
- }
- func builtinMax(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- if _, ok := ctx["$agg0"]; ok {
- return
- }
- fn := ctx["$fn"]
- if _, ok := ctx["$agg"]; ok {
- if v, ok = ctx[fn]; ok {
- return
- }
- return nil, nil
- }
- max := ctx[fn]
- y := arg[0]
- if y == nil {
- return
- }
- switch x := max.(type) {
- case nil:
- switch y := y.(type) {
- case float32, float64, string, int8, int16, int32, int64, uint8, uint16, uint32, uint64, time.Time:
- max = y
- default:
- return nil, fmt.Errorf("max: cannot accept %v (value if type %T)", y, y)
- }
- case float32:
- if y := y.(float32); y > x {
- max = y
- }
- case float64:
- if y := y.(float64); y > x {
- max = y
- }
- case string:
- if y := y.(string); y > x {
- max = y
- }
- case int8:
- if y := y.(int8); y > x {
- max = y
- }
- case int16:
- if y := y.(int16); y > x {
- max = y
- }
- case int32:
- if y := y.(int32); y > x {
- max = y
- }
- case int64:
- if y := y.(int64); y > x {
- max = y
- }
- case uint8:
- if y := y.(uint8); y > x {
- max = y
- }
- case uint16:
- if y := y.(uint16); y > x {
- max = y
- }
- case uint32:
- if y := y.(uint32); y > x {
- max = y
- }
- case uint64:
- if y := y.(uint64); y > x {
- max = y
- }
- case time.Time:
- if y := y.(time.Time); y.After(x) {
- max = y
- }
- }
- ctx[fn] = max
- return
- }
- func builtinMin(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- if _, ok := ctx["$agg0"]; ok {
- return
- }
- fn := ctx["$fn"]
- if _, ok := ctx["$agg"]; ok {
- if v, ok = ctx[fn]; ok {
- return
- }
- return nil, nil
- }
- min := ctx[fn]
- y := arg[0]
- if y == nil {
- return
- }
- switch x := min.(type) {
- case nil:
- switch y := y.(type) {
- case float32, float64, string, int8, int16, int32, int64, uint8, uint16, uint32, uint64, time.Time:
- min = y
- default:
- return nil, fmt.Errorf("min: cannot accept %v (value if type %T)", y, y)
- }
- case float32:
- if y := y.(float32); y < x {
- min = y
- }
- case float64:
- if y := y.(float64); y < x {
- min = y
- }
- case string:
- if y := y.(string); y < x {
- min = y
- }
- case int8:
- if y := y.(int8); y < x {
- min = y
- }
- case int16:
- if y := y.(int16); y < x {
- min = y
- }
- case int32:
- if y := y.(int32); y < x {
- min = y
- }
- case int64:
- if y := y.(int64); y < x {
- min = y
- }
- case uint8:
- if y := y.(uint8); y < x {
- min = y
- }
- case uint16:
- if y := y.(uint16); y < x {
- min = y
- }
- case uint32:
- if y := y.(uint32); y < x {
- min = y
- }
- case uint64:
- if y := y.(uint64); y < x {
- min = y
- }
- case time.Time:
- if y := y.(time.Time); y.Before(x) {
- min = y
- }
- }
- ctx[fn] = min
- return
- }
- func builtinMinute(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Minute()), nil
- default:
- return nil, invArg(x, "minute")
- }
- }
- func builtinMinutes(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Duration:
- return x.Minutes(), nil
- default:
- return nil, invArg(x, "minutes")
- }
- }
- func builtinMonth(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Month()), nil
- default:
- return nil, invArg(x, "month")
- }
- }
- func builtinNanosecond(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Nanosecond()), nil
- default:
- return nil, invArg(x, "nanosecond")
- }
- }
- func builtinNanoseconds(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Duration:
- return x.Nanoseconds(), nil
- default:
- return nil, invArg(x, "nanoseconds")
- }
- }
- func builtinNow(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- return time.Now(), nil
- }
- func builtinParseTime(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- var a [2]string
- for i, v := range arg {
- switch x := v.(type) {
- case nil:
- return nil, nil
- case string:
- a[i] = x
- default:
- return nil, invArg(x, "parseTime")
- }
- }
- t, err := time.Parse(a[0], a[1])
- if err != nil {
- return nil, err
- }
- ls := t.Location().String()
- if ls == "UTC" {
- return t, nil
- }
- l, err := time.LoadLocation(ls)
- if err != nil {
- return t, nil
- }
- return time.ParseInLocation(a[0], a[1], l)
- }
- func builtinReal(arg []interface{}, _ map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case idealComplex:
- return real(x), nil
- case complex64:
- return real(x), nil
- case complex128:
- return real(x), nil
- default:
- return nil, invArg(x, "real")
- }
- }
- func builtinSecond(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Second()), nil
- default:
- return nil, invArg(x, "second")
- }
- }
- func builtinSeconds(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Duration:
- return x.Seconds(), nil
- default:
- return nil, invArg(x, "seconds")
- }
- }
- func builtinSince(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return time.Since(x), nil
- default:
- return nil, invArg(x, "since")
- }
- }
- func builtinSum(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- if _, ok := ctx["$agg0"]; ok {
- return
- }
- fn := ctx["$fn"]
- if _, ok := ctx["$agg"]; ok {
- if v, ok = ctx[fn]; ok {
- return
- }
- return nil, nil
- }
- sum := ctx[fn]
- y := arg[0]
- if y == nil {
- return
- }
- switch x := sum.(type) {
- case nil:
- switch y := y.(type) {
- case complex64, complex128, float32, float64, int8, int16, int32, int64, uint8, uint16, uint32, uint64:
- sum = y
- default:
- return nil, fmt.Errorf("sum: cannot accept %v (value if type %T)", y, y)
- }
- case complex64:
- sum = x + y.(complex64)
- case complex128:
- sum = x + y.(complex128)
- case float32:
- sum = x + y.(float32)
- case float64:
- sum = x + y.(float64)
- case int8:
- sum = x + y.(int8)
- case int16:
- sum = x + y.(int16)
- case int32:
- sum = x + y.(int32)
- case int64:
- sum = x + y.(int64)
- case uint8:
- sum = x + y.(uint8)
- case uint16:
- sum = x + y.(uint16)
- case uint32:
- sum = x + y.(uint32)
- case uint64:
- sum = x + y.(uint64)
- }
- ctx[fn] = sum
- return
- }
- func builtinTimeIn(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- switch y := arg[1].(type) {
- case nil:
- return nil, nil
- case string:
- loc := time.Local
- switch y {
- case "local":
- default:
- loc, err = time.LoadLocation(y)
- if err != nil {
- return
- }
- }
- return x.In(loc), nil
- default:
- return nil, invArg(x, "timeIn")
- }
- default:
- return nil, invArg(x, "timeIn")
- }
- }
- func builtinWeekday(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Weekday()), nil
- default:
- return nil, invArg(x, "weekday")
- }
- }
- func builtinYear(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.Year()), nil
- default:
- return nil, invArg(x, "year")
- }
- }
- func builtinYearday(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
- switch x := arg[0].(type) {
- case nil:
- return nil, nil
- case time.Time:
- return int64(x.YearDay()), nil
- default:
- return nil, invArg(x, "yearDay")
- }
- }
|