syncthing/vendor/github.com/cznic/ql/etc.go
2017-04-05 14:34:41 +00:00

2773 lines
47 KiB
Go

// 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 (
"bytes"
"fmt"
"io"
"math"
"math/big"
"time"
)
// QL types.
const (
qBool = 0x62 // 'b'
qComplex64 = 0x63 // 'c'
qComplex128 = 0x64 // 'd'
qFloat32 = 0x66 // 'f'
qFloat64 = 0x67 // 'g', alias float
qInt8 = 0x69 // 'i'
qInt16 = 0x6a // 'j'
qInt32 = 0x6b // 'k'
qInt64 = 0x6c // 'l', alias int
qString = 0x73 // 's'
qUint8 = 0x75 // 'u', alias byte
qUint16 = 0x76 // 'v'
qUint32 = 0x77 // 'w'
qUint64 = 0x78 // 'x', alias uint
qBigInt = 0x49 // 'I'
qBigRat = 0x52 // 'R'
qBlob = 0x42 // 'B'
qDuration = 0x44 // 'D'
qTime = 0x54 // 'T'
)
var (
type2Str = map[int]string{
qBigInt: "bigint",
qBigRat: "bigrat",
qBlob: "blob",
qBool: "bool",
qComplex128: "complex128",
qComplex64: "complex64",
qDuration: "duration",
qFloat32: "float32",
qFloat64: "float64",
qInt16: "int16",
qInt32: "int32",
qInt64: "int64",
qInt8: "int8",
qString: "string",
qTime: "time",
qUint16: "uint16",
qUint32: "uint32",
qUint64: "uint64",
qUint8: "uint8",
}
)
func typeStr(typ int) (r string) {
return type2Str[typ]
}
func noEOF(err error) error {
if err == io.EOF {
err = nil
}
return err
}
func runErr(err error) error { return fmt.Errorf("run time error: %s", err) }
func invXOp(s, x interface{}) error {
return fmt.Errorf("invalid operation: %v[%v] (index of type %T)", s, x, x)
}
func invSOp(s interface{}) error {
return fmt.Errorf("cannot slice %s (type %T)", s, s)
}
func invNegX(x interface{}) error {
return fmt.Errorf("invalid string index %v (index must be non-negative)", x)
}
func invNegLO(x interface{}) error {
return fmt.Errorf("invalid LIMIT or OFFSET value %v (must be non-negative)", x)
}
func invSliceNegX(x interface{}) error {
return fmt.Errorf("invalid slice index %v (index must be non-negative)", x)
}
func invBoundX(s string, x uint64) error {
return fmt.Errorf("invalid string index %d (out of bounds for %d-byte string)", x, len(s))
}
func invSliceBoundX(s string, x uint64) error {
return fmt.Errorf("invalid slice index %d (out of bounds for %d-byte string)", x, len(s))
}
func intExpr(x interface{}) (i int64, err error) {
switch x := x.(type) {
case idealInt:
if x < 0 {
return 0, invNegLO(x)
}
return int64(x), nil
case idealRune:
if x < 0 {
return 0, invNegLO(x)
}
return int64(x), nil
case idealUint:
if x < 0 {
return 0, invNegLO(x)
}
return int64(x), nil
case int8:
if x < 0 {
return 0, invNegLO(x)
}
return int64(x), nil
case int16:
if x < 0 {
return 0, invNegLO(x)
}
return int64(x), nil
case int32:
if x < 0 {
return 0, invNegLO(x)
}
return int64(x), nil
case int64:
if x < 0 {
return 0, invNegLO(x)
}
return x, nil
case uint8:
return int64(x), nil
case uint16:
return int64(x), nil
case uint32:
return int64(x), nil
case uint64:
return int64(x), nil
default:
return 0, fmt.Errorf("non-integer expression: %v (value of type %T)", x, x)
}
}
func limOffExpr(x interface{}) (i uint64, err error) {
switch x := x.(type) {
case idealInt:
if x < 0 {
return 0, invNegLO(x)
}
return uint64(x), nil
case idealRune:
if x < 0 {
return 0, invNegLO(x)
}
return uint64(x), nil
case idealUint:
if x < 0 {
return 0, invNegLO(x)
}
return uint64(x), nil
case int8:
if x < 0 {
return 0, invNegLO(x)
}
return uint64(x), nil
case int16:
if x < 0 {
return 0, invNegLO(x)
}
return uint64(x), nil
case int32:
if x < 0 {
return 0, invNegLO(x)
}
return uint64(x), nil
case int64:
if x < 0 {
return 0, invNegLO(x)
}
return uint64(x), nil
case uint8:
return uint64(x), nil
case uint16:
return uint64(x), nil
case uint32:
return uint64(x), nil
case uint64:
return x, nil
default:
return 0, fmt.Errorf("non-integer used in LIMIT or OFFSET: %v (value of type %T)", x, x)
}
}
func indexExpr(s *string, x interface{}) (i uint64, err error) {
switch x := x.(type) {
case idealFloat:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && int(x) >= len(*s) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case idealInt:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && int64(x) >= int64(len(*s)) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case idealRune:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && int32(x) >= int32(len(*s)) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case idealUint:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && uint64(x) >= uint64(len(*s)) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case int8:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && int(x) >= len(*s) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case int16:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && int(x) >= len(*s) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case int32:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && int(x) >= len(*s) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case int64:
if x < 0 {
return 0, invNegX(x)
}
if s != nil && x >= int64(len(*s)) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint8:
if s != nil && int(x) >= len(*s) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint16:
if s != nil && int(x) >= len(*s) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint32:
if s != nil && x >= uint32(len(*s)) {
return 0, invBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint64:
if s != nil && x >= uint64(len(*s)) {
return 0, invBoundX(*s, x)
}
return x, nil
default:
return 0, fmt.Errorf("non-integer string index %v (value of type %T)", x, x)
}
}
func sliceExpr(s *string, x interface{}, mod int) (i uint64, err error) {
switch x := x.(type) {
case idealFloat:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && int(x) >= len(*s)+mod {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case idealInt:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && int64(x) >= int64(len(*s)+mod) {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case idealRune:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && int32(x) >= int32(len(*s)+mod) {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case idealUint:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && uint64(x) >= uint64(len(*s)+mod) {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case int8:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && int(x) >= len(*s)+mod {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case int16:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && int(x) >= len(*s)+mod {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case int32:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && int(x) >= len(*s)+mod {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case int64:
if x < 0 {
return 0, invSliceNegX(x)
}
if s != nil && x >= int64(len(*s)+mod) {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint8:
if s != nil && int(x) >= len(*s)+mod {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint16:
if s != nil && int(x) >= len(*s)+mod {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint32:
if s != nil && x >= uint32(len(*s)+mod) {
return 0, invSliceBoundX(*s, uint64(x))
}
return uint64(x), nil
case uint64:
if s != nil && x >= uint64(len(*s)+mod) {
return 0, invSliceBoundX(*s, x)
}
return x, nil
default:
return 0, fmt.Errorf("invalid slice index %s (type %T)", x, x)
}
}
type iop int
func (o iop) String() string {
switch i := int(o); i {
case andand:
return "&&"
case andnot:
return "&^"
case lsh:
return "<<"
case le:
return "<="
case eq:
return "=="
case ge:
return ">="
case neq:
return "!="
case oror:
return "||"
case rsh:
return ">>"
default:
return string(i)
}
}
func ideal(v interface{}) interface{} {
switch x := v.(type) {
case idealComplex:
return complex128(x)
case idealFloat:
return float64(x)
case idealInt:
return int64(x)
case idealRune:
return int64(x)
case idealUint:
return uint64(x)
default:
return v
}
}
func eval(v expression, execCtx *execCtx, ctx map[interface{}]interface{}) (y interface{}) {
y, err := expand1(v.eval(execCtx, ctx))
if err != nil {
panic(err) // panic ok here
}
return
}
func eval2(a, b expression, execCtx *execCtx, ctx map[interface{}]interface{}) (x, y interface{}) {
return eval(a, execCtx, ctx), eval(b, execCtx, ctx)
}
func invOp2(x, y interface{}, o int) (interface{}, error) {
return nil, fmt.Errorf("invalid operation: %v %v %v (mismatched types %T and %T)", x, iop(o), y, ideal(x), ideal(y))
}
func undOp(x interface{}, o int) (interface{}, error) {
return nil, fmt.Errorf("invalid operation: %v%v (operator %v not defined on %T)", iop(o), x, iop(o), x)
}
func undOp2(x, y interface{}, o int) (interface{}, error) {
return nil, fmt.Errorf("invalid operation: %v %v %v (operator %v not defined on %T)", x, iop(o), y, iop(o), x)
}
func invConv(val interface{}, typ int) (interface{}, error) {
return nil, fmt.Errorf("cannot convert %v (type %T) to type %s", val, val, typeStr(typ))
}
func truncConv(val interface{}) (interface{}, error) {
return nil, fmt.Errorf("constant %v truncated to integer", val)
}
func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
if val == nil {
return nil, nil
}
switch typ {
case qBool:
switch x := val.(type) {
//case nil:
//case idealComplex:
//case idealFloat:
//case idealInt:
//case idealRune:
//case idealUint:
case bool:
return x, nil
//case complex64:
//case complex128:
//case float32:
//case float64:
//case int8:
//case int16:
//case int32:
//case int64:
//case string:
//case uint8:
//case uint16:
//case uint32:
//case uint64:
default:
return invConv(val, typ)
}
case qComplex64:
switch x := val.(type) {
//case nil:
case idealComplex:
return complex64(x), nil
case idealFloat:
return complex(float32(x), 0), nil
case idealInt:
return complex(float32(x), 0), nil
case idealRune:
return complex(float32(x), 0), nil
case idealUint:
return complex(float32(x), 0), nil
//case bool:
case complex64:
return x, nil
case complex128:
return complex64(x), nil
//case float32:
//case float64:
//case int8:
//case int16:
//case int32:
//case int64:
//case string:
//case uint8:
//case uint16:
//case uint32:
//case uint64:
default:
return invConv(val, typ)
}
case qComplex128:
switch x := val.(type) {
//case nil:
case idealComplex:
return complex128(x), nil
case idealFloat:
return complex(float64(x), 0), nil
case idealInt:
return complex(float64(x), 0), nil
case idealRune:
return complex(float64(x), 0), nil
case idealUint:
return complex(float64(x), 0), nil
//case bool:
case complex64:
return complex128(x), nil
case complex128:
return x, nil
//case float32:
//case float64:
//case int8:
//case int16:
//case int32:
//case int64:
//case string:
//case uint8:
//case uint16:
//case uint32:
//case uint64:
default:
return invConv(val, typ)
}
case qFloat32:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
return float32(x), nil
case idealInt:
return float32(x), nil
case idealRune:
return float32(x), nil
case idealUint:
return float32(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return x, nil
case float64:
return float32(x), nil
case int8:
return float32(x), nil
case int16:
return float32(x), nil
case int32:
return float32(x), nil
case int64:
return float32(x), nil
//case string:
case uint8:
return float32(x), nil
case uint16:
return float32(x), nil
case uint32:
return float32(x), nil
case uint64:
return float32(x), nil
case *big.Int:
v, _ := big.NewRat(1, 1).SetInt(x).Float64()
return float32(v), nil
case *big.Rat:
v, _ := x.Float64()
return float32(v), nil
case time.Duration:
return float32(x), nil
default:
return invConv(val, typ)
}
case qFloat64:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
return float64(x), nil
case idealInt:
return float64(x), nil
case idealRune:
return float64(x), nil
case idealUint:
return float64(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return float64(x), nil
case float64:
return x, nil
case int8:
return float64(x), nil
case int16:
return float64(x), nil
case int32:
return float64(x), nil
case int64:
return float64(x), nil
//case string:
case uint8:
return float64(x), nil
case uint16:
return float64(x), nil
case uint32:
return float64(x), nil
case uint64:
return float64(x), nil
case *big.Int:
v, _ := big.NewRat(1, 1).SetInt(x).Float64()
return v, nil
case *big.Rat:
v, _ := x.Float64()
return v, nil
case time.Duration:
return float64(x), nil
default:
return invConv(val, typ)
}
case qInt8:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return int8(x), nil
case idealInt:
return int8(x), nil
case idealRune:
return int8(x), nil
case idealUint:
return int8(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return int8(x), nil
case float64:
return int8(x), nil
case int8:
return x, nil
case int16:
return int8(x), nil
case int32:
return int8(x), nil
case int64:
return int8(x), nil
//case string:
case uint8:
return int8(x), nil
case uint16:
return int8(x), nil
case uint32:
return int8(x), nil
case uint64:
return int8(x), nil
case *big.Int:
return int8(x.Int64()), nil
case time.Duration:
return int8(x), nil
default:
return invConv(val, typ)
}
case qInt16:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return int16(x), nil
case idealInt:
return int16(x), nil
case idealRune:
return int16(x), nil
case idealUint:
return int16(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return int16(x), nil
case float64:
return int16(x), nil
case int8:
return int16(x), nil
case int16:
return x, nil
case int32:
return int16(x), nil
case int64:
return int16(x), nil
//case string:
case uint8:
return int16(x), nil
case uint16:
return int16(x), nil
case uint32:
return int16(x), nil
case uint64:
return int16(x), nil
case *big.Int:
return int16(x.Int64()), nil
case time.Duration:
return int16(x), nil
default:
return invConv(val, typ)
}
case qInt32:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return int32(x), nil
case idealInt:
return int32(x), nil
case idealRune:
return int32(x), nil
case idealUint:
return int32(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return int32(x), nil
case float64:
return int32(x), nil
case int8:
return int32(x), nil
case int16:
return int32(x), nil
case int32:
return x, nil
case int64:
return int32(x), nil
//case string:
case uint8:
return int32(x), nil
case uint16:
return int32(x), nil
case uint32:
return int32(x), nil
case uint64:
return int32(x), nil
case *big.Int:
return int32(x.Int64()), nil
case time.Duration:
return int32(x), nil
default:
return invConv(val, typ)
}
case qInt64:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return int64(x), nil
case idealInt:
return int64(x), nil
case idealRune:
return int64(x), nil
case idealUint:
return int64(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return int64(x), nil
case float64:
return int64(x), nil
case int8:
return int64(x), nil
case int16:
return int64(x), nil
case int32:
return int64(x), nil
case int64:
return x, nil
//case string:
case uint8:
return int64(x), nil
case uint16:
return int64(x), nil
case uint32:
return int64(x), nil
case uint64:
return int64(x), nil
case *big.Int:
return x.Int64(), nil
case time.Duration:
return int64(x), nil
default:
return invConv(val, typ)
}
case qString:
switch x := val.(type) {
//case nil:
//case idealComplex:
//case idealFloat:
case idealInt:
return string(x), nil
case idealRune:
return string(x), nil
case idealUint:
return string(x), nil
//case bool:
//case complex64:
//case complex128:
//case float32:
//case float64:
case int8:
return string(x), nil
case int16:
return string(x), nil
case int32:
return string(x), nil
case int64:
return string(x), nil
case string:
return x, nil
case uint8:
return string(x), nil
case uint16:
return string(x), nil
case uint32:
return string(x), nil
case uint64:
return string(x), nil
case []byte:
return string(x), nil
case *big.Int:
return x.String(), nil
case time.Time:
return x.String(), nil
case time.Duration:
return x.String(), nil
default:
return invConv(val, typ)
}
case qUint8:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return uint8(x), nil
case idealInt:
return uint8(x), nil
case idealRune:
return uint8(x), nil
case idealUint:
return uint8(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return uint8(x), nil
case float64:
return uint8(x), nil
case int8:
return uint8(x), nil
case int16:
return uint8(x), nil
case int32:
return uint8(x), nil
case int64:
return uint8(x), nil
//case string:
case uint8:
return x, nil
case uint16:
return uint8(x), nil
case uint32:
return uint8(x), nil
case uint64:
return uint8(x), nil
case *big.Int:
return uint8(x.Int64()), nil
case time.Duration:
return uint8(x), nil
default:
return invConv(val, typ)
}
case qUint16:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return uint16(x), nil
case idealInt:
return uint16(x), nil
case idealRune:
return uint16(x), nil
case idealUint:
return uint16(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return uint16(x), nil
case float64:
return uint16(x), nil
case int8:
return uint16(x), nil
case int16:
return uint16(x), nil
case int32:
return uint16(x), nil
case int64:
return uint16(x), nil
//case string:
case uint8:
return uint16(x), nil
case uint16:
return x, nil
case uint32:
return uint16(x), nil
case uint64:
return uint16(x), nil
case *big.Int:
return uint16(x.Int64()), nil
case time.Duration:
return uint16(x), nil
default:
return invConv(val, typ)
}
case qUint32:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return uint32(x), nil
case idealInt:
return uint32(x), nil
case idealRune:
return uint32(x), nil
case idealUint:
return uint32(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return uint32(x), nil
case float64:
return uint32(x), nil
case int8:
return uint32(x), nil
case int16:
return uint32(x), nil
case int32:
return uint32(x), nil
case int64:
return uint32(x), nil
//case string:
case uint8:
return uint32(x), nil
case uint16:
return uint32(x), nil
case uint32:
return x, nil
case uint64:
return uint32(x), nil
case *big.Int:
return uint32(x.Int64()), nil
case time.Duration:
return uint32(x), nil
default:
return invConv(val, typ)
}
case qUint64:
switch x := val.(type) {
//case nil:
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
return uint64(x), nil
case idealInt:
return uint64(x), nil
case idealRune:
return uint64(x), nil
case idealUint:
return uint64(x), nil
//case bool:
//case complex64:
//case complex128:
case float32:
return uint64(x), nil
case float64:
return uint64(x), nil
case int8:
return uint64(x), nil
case int16:
return uint64(x), nil
case int32:
return uint64(x), nil
case int64:
return uint64(x), nil
//case string:
case uint8:
return uint64(x), nil
case uint16:
return uint64(x), nil
case uint32:
return uint64(x), nil
case uint64:
return x, nil
case *big.Int:
return x.Uint64(), nil
case time.Duration:
return uint64(x), nil
default:
return invConv(val, typ)
}
case qBlob:
switch x := val.(type) {
case string:
return []byte(x), nil
case []byte:
return x, nil
default:
return invConv(val, typ)
}
case qBigInt:
switch x := val.(type) {
// case blob
// case bool
//case idealComplex:
case idealFloat:
if _, frac := math.Modf(float64(x)); frac != 0 {
return truncConv(x)
}
rr := big.NewRat(1, 1).SetFloat64(float64(x))
ii := big.NewInt(0).Set(rr.Num())
ii.Quo(ii, rr.Denom())
return ii, nil
case idealInt:
return big.NewInt(0).SetInt64(int64(x)), nil
case idealRune:
return big.NewInt(0).SetInt64(int64(x)), nil
case idealUint:
return big.NewInt(0).SetUint64(uint64(x)), nil
//case complex64
//case complex128
case float32:
rr := big.NewRat(1, 1).SetFloat64(float64(x))
ii := big.NewInt(0).Set(rr.Num())
ii.Quo(ii, rr.Denom())
return ii, nil
case float64:
rr := big.NewRat(1, 1).SetFloat64(x)
ii := big.NewInt(0).Set(rr.Num())
ii.Quo(ii, rr.Denom())
return ii, nil
case int8:
return big.NewInt(0).SetInt64(int64(x)), nil
case int16:
return big.NewInt(0).SetInt64(int64(x)), nil
case int32:
return big.NewInt(0).SetInt64(int64(x)), nil
case int64:
return big.NewInt(0).SetInt64(x), nil
case string:
y := big.NewInt(0)
if _, ok := y.SetString(x, 0); !ok {
return invConv(val, typ)
}
return y, nil
case uint8:
return big.NewInt(0).SetUint64(uint64(x)), nil
case uint16:
return big.NewInt(0).SetUint64(uint64(x)), nil
case uint32:
return big.NewInt(0).SetUint64(uint64(x)), nil
case uint64:
return big.NewInt(0).SetUint64(x), nil
case *big.Int:
return x, nil
case *big.Rat:
ii := big.NewInt(0).Set(x.Num())
ii.Div(ii, x.Denom())
return ii, nil
default:
return invConv(val, typ)
}
case qBigRat:
switch x := val.(type) {
// case blob
// case bool
//case idealComplex:
case idealFloat:
return big.NewRat(1, 1).SetFloat64(float64(x)), nil
case idealInt:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case idealRune:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case idealUint:
return big.NewRat(1, 1).SetInt(big.NewInt(0).SetUint64(uint64(x))), nil
//case complex64
//case complex128
case float32:
return big.NewRat(1, 1).SetFloat64(float64(x)), nil
case float64:
return big.NewRat(1, 1).SetFloat64(x), nil
case int8:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case int16:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case int32:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case int64:
return big.NewRat(1, 1).SetInt64(x), nil
case string:
y := big.NewRat(1, 1)
if _, ok := y.SetString(x); !ok {
return invConv(val, typ)
}
return y, nil
case uint8:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case uint16:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case uint32:
return big.NewRat(1, 1).SetInt64(int64(x)), nil
case uint64:
return big.NewRat(1, 1).SetInt(big.NewInt(0).SetUint64(x)), nil
case *big.Int:
return big.NewRat(1, 1).SetInt(x), nil
case *big.Rat:
return x, nil
default:
return invConv(val, typ)
}
case qDuration:
switch x := val.(type) {
// case blob
// case bool
//case idealComplex:
case idealFloat:
return time.Duration(x), nil
case idealInt:
return time.Duration(x), nil
case idealRune:
return time.Duration(x), nil
case idealUint:
return time.Duration(x), nil
//case complex64
//case complex128
case float32:
return time.Duration(x), nil
case float64:
return time.Duration(x), nil
case int8:
return time.Duration(x), nil
case int16:
return time.Duration(x), nil
case int32:
return time.Duration(x), nil
case int64:
return time.Duration(x), nil
case string:
return time.ParseDuration(x)
case uint8:
return time.Duration(x), nil
case uint16:
return time.Duration(x), nil
case uint32:
return time.Duration(x), nil
case uint64:
return time.Duration(x), nil
case *big.Int:
return time.Duration(x.Int64()), nil
case *big.Rat:
f, _ := x.Float64()
return time.Duration(f), nil
case time.Duration:
return x, nil
default:
return invConv(val, typ)
}
case qTime:
switch x := val.(type) {
// case blob
// case bool
//case idealComplex:
//case idealFloat:
//case idealInt:
//case idealRune:
//case idealUint:
//case complex64
//case complex128
//case float32:
//case float64:
//case int8:
//case int16:
//case int32:
//case int64:
//case string:
//case uint8:
//case uint16:
//case uint32:
//case uint64:
//case *big.Int:
//case *big.Rat:
//case time.Duration:
case time.Time:
return x, nil
default:
return invConv(val, typ)
}
default:
panic("internal error 006")
}
}
func invShiftRHS(lhs, rhs interface{}) (interface{}, error) {
return nil, fmt.Errorf("invalid operation: %v << %v (shift count type %T, must be unsigned integer)", lhs, rhs, rhs)
}
func invTruncInt(v interface{}) error {
return fmt.Errorf("constant %v truncated to integer", v)
}
func overflow(v interface{}, typ int) error {
return fmt.Errorf("constant %v overflows %s", v, typeStr(typ))
}
func typeCheck1(val interface{}, c *col) (interface{}, error) {
rec := []interface{}{val}
c = c.clone()
c.index = 0
if err := typeCheck(rec, []*col{c}); err != nil {
return nil, err
}
return rec[0], nil
}
func typeCheck(rec []interface{}, cols []*col) (err error) {
for _, c := range cols {
i := c.index
if v := rec[i]; !c.typeCheck(v) {
switch v.(type) {
case idealComplex:
y := complex128(v.(idealComplex))
switch c.typ {
case qBool:
case qComplex64:
rec[i] = complex64(y)
continue
case qComplex128:
rec[i] = y
continue
case qFloat32, qFloat64, qInt8, qInt16, qInt32, qInt64, qUint8, qUint16, qUint32, qUint64:
return fmt.Errorf("constant %v truncated to real", y)
}
case idealFloat:
y := float64(v.(idealFloat))
switch c.typ {
case qBool:
case qComplex64:
rec[i] = complex(float32(y), 0)
continue
case qComplex128:
rec[i] = complex(y, 0)
continue
case qFloat32:
rec[i] = float32(y)
continue
case qFloat64:
rec[i] = y
continue
case qInt8:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < math.MinInt8 || y > math.MaxInt8 {
return overflow(y, c.typ)
}
rec[i] = int8(y)
continue
case qInt16:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < math.MinInt16 || y > math.MaxInt16 {
return overflow(y, c.typ)
}
rec[i] = int16(y)
continue
case qInt32:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < math.MinInt32 || y > math.MaxInt32 {
return overflow(y, c.typ)
}
rec[i] = int32(y)
continue
case qInt64:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < math.MinInt64 || y > math.MaxInt64 {
return overflow(y, c.typ)
}
rec[i] = int64(y)
continue
case qString:
case qUint8:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < 0 || y > math.MaxUint8 {
return overflow(y, c.typ)
}
rec[i] = uint8(y)
continue
case qUint16:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < 0 || y > math.MaxUint16 {
return overflow(y, c.typ)
}
rec[i] = uint16(y)
continue
case qUint32:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < 0 || y > math.MaxUint32 {
return overflow(y, c.typ)
}
rec[i] = uint32(y)
continue
case qUint64:
if math.Floor(y) != y {
return invTruncInt(y)
}
if y < 0 || y > math.MaxUint64 {
return overflow(y, c.typ)
}
rec[i] = uint64(y)
continue
case qBigInt:
if math.Floor(y) != y {
return invTruncInt(y)
}
rr := big.NewRat(1, 1).SetFloat64(y)
ii := big.NewInt(0)
ii.Set(rr.Num())
ii.Quo(ii, rr.Denom())
rec[i] = ii
continue
case qBigRat:
rec[i] = big.NewRat(1, 1).SetFloat64(y)
continue
}
case idealInt:
y := int64(v.(idealInt))
switch c.typ {
case qBool:
case qComplex64:
rec[i] = complex(float32(y), 0)
continue
case qComplex128:
rec[i] = complex(float64(y), 0)
continue
case qFloat32:
rec[i] = float32(y)
continue
case qFloat64:
rec[i] = float64(y)
continue
case qInt8:
if y < math.MinInt8 || y > math.MaxInt8 {
return overflow(y, c.typ)
}
rec[i] = int8(y)
continue
case qInt16:
if y < math.MinInt16 || y > math.MaxInt16 {
return overflow(y, c.typ)
}
rec[i] = int16(y)
continue
case qInt32:
if y < math.MinInt32 || y > math.MaxInt32 {
return overflow(y, c.typ)
}
rec[i] = int32(y)
continue
case qInt64:
if y < math.MinInt64 || y > math.MaxInt64 {
return overflow(y, c.typ)
}
rec[i] = y
continue
case qString:
case qUint8:
if y < 0 || y > math.MaxUint8 {
return overflow(y, c.typ)
}
rec[i] = uint8(y)
continue
case qUint16:
if y < 0 || y > math.MaxUint16 {
return overflow(y, c.typ)
}
rec[i] = uint16(y)
continue
case qUint32:
if y < 0 || y > math.MaxUint32 {
return overflow(y, c.typ)
}
rec[i] = uint32(y)
continue
case qUint64:
if y < 0 {
return overflow(y, c.typ)
}
rec[i] = uint64(y)
continue
case qBigInt:
rec[i] = big.NewInt(y)
continue
case qBigRat:
rec[i] = big.NewRat(1, 1).SetInt64(y)
continue
}
case idealRune:
y := int64(v.(idealRune))
switch c.typ {
case qBool:
case qComplex64:
rec[i] = complex(float32(y), 0)
continue
case qComplex128:
rec[i] = complex(float64(y), 0)
continue
case qFloat32:
rec[i] = float32(y)
continue
case qFloat64:
rec[i] = float64(y)
continue
case qInt8:
if y < math.MinInt8 || y > math.MaxInt8 {
return overflow(y, c.typ)
}
rec[i] = int8(y)
continue
case qInt16:
if y < math.MinInt16 || y > math.MaxInt16 {
return overflow(y, c.typ)
}
rec[i] = int16(y)
continue
case qInt32:
if y < math.MinInt32 || y > math.MaxInt32 {
return overflow(y, c.typ)
}
rec[i] = int32(y)
continue
case qInt64:
if y < math.MinInt64 || y > math.MaxInt64 {
return overflow(y, c.typ)
}
rec[i] = y
continue
case qString:
case qUint8:
if y < 0 || y > math.MaxUint8 {
return overflow(y, c.typ)
}
rec[i] = uint8(y)
continue
case qUint16:
if y < 0 || y > math.MaxUint16 {
return overflow(y, c.typ)
}
rec[i] = uint16(y)
continue
case qUint32:
if y < 0 {
return overflow(y, c.typ)
}
rec[i] = uint32(y)
continue
case qUint64:
if y < 0 {
return overflow(y, c.typ)
}
rec[i] = uint64(y)
continue
case qBigInt:
rec[i] = big.NewInt(y)
continue
case qBigRat:
rec[i] = big.NewRat(1, 1).SetInt64(y)
continue
}
case idealUint:
y := uint64(v.(idealUint))
switch c.typ {
case qBool:
case qComplex64:
rec[i] = complex(float32(y), 0)
continue
case qComplex128:
rec[i] = complex(float64(y), 0)
continue
case qFloat32:
rec[i] = float32(y)
continue
case qFloat64:
rec[i] = float64(y)
continue
case qInt8:
if y > math.MaxInt8 {
return overflow(y, c.typ)
}
rec[i] = int8(y)
continue
case qInt16:
if y > math.MaxInt16 {
return overflow(y, c.typ)
}
rec[i] = int16(y)
continue
case qInt32:
if y > math.MaxInt32 {
return overflow(y, c.typ)
}
rec[i] = int32(y)
continue
case qInt64:
if y > math.MaxInt64 {
return overflow(y, c.typ)
}
rec[i] = int64(y)
continue
case qString:
rec[i] = string(y)
continue
case qUint8:
if y > math.MaxUint8 {
return overflow(y, c.typ)
}
rec[i] = uint8(y)
continue
case qUint16:
if y > math.MaxUint16 {
return overflow(y, c.typ)
}
rec[i] = uint16(y)
continue
case qUint32:
if y > math.MaxUint32 {
return overflow(y, c.typ)
}
rec[i] = uint32(y)
continue
case qUint64:
rec[i] = y
continue
case qBigInt:
rec[i] = big.NewInt(0).SetUint64(y)
continue
case qBigRat:
ii := big.NewInt(0).SetUint64(y)
rec[i] = big.NewRat(1, 1).SetInt(ii)
continue
}
}
return fmt.Errorf("cannot use %v (type %T) in assignment to, or comparison with, column %s (type %s)", v, ideal(v), c.name, typeStr(c.typ))
}
}
return
}
//TODO collate1 should return errors instead of panicing
func collate1(a, b interface{}) int {
switch x := a.(type) {
case nil:
if b != nil {
return -1
}
return 0
case bool:
switch y := b.(type) {
case nil:
return 1
case bool:
if !x && y {
return -1
}
if x == y {
return 0
}
return 1
default:
// Make bool collate before anything except nil and
// other bool for index seeking first non NULL value.
return -1
}
case idealComplex:
switch y := b.(type) {
case nil:
return 1
case idealComplex:
if x == y {
return 0
}
if real(x) < real(y) {
return -1
}
if real(x) > real(y) {
return 1
}
if imag(x) < imag(y) {
return -1
}
return 1
case complex64:
{
x, y := complex64(x), y
if x == y {
return 0
}
if real(x) < real(y) {
return -1
}
if real(x) > real(y) {
return 1
}
if imag(x) < imag(y) {
return -1
}
return 1
}
case complex128:
{
x := complex128(x)
if x == y {
return 0
}
if real(x) < real(y) {
return -1
}
if real(x) > real(y) {
return 1
}
if imag(x) < imag(y) {
return -1
}
return 1
}
default:
panic("internal error 012")
}
case idealUint:
switch y := b.(type) {
case nil:
return 1
case idealUint:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case uint8:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case uint16:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case uint32:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case uint64:
{
x, y := uint64(x), y
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case uint:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 013")
}
case idealRune:
switch y := b.(type) {
case nil:
return 1
case idealRune:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case int8:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int16:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int32:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int64:
{
x, y := int64(x), y
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 014")
}
case idealInt:
switch y := b.(type) {
case nil:
return 1
case idealInt:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case int8:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int16:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int32:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int64:
{
x, y := int64(x), y
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case int:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 015")
}
case idealFloat:
switch y := b.(type) {
case nil:
return 1
case idealFloat:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case float32:
{
x, y := float64(x), float64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case float64:
{
x, y := float64(x), y
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 016")
}
case complex64:
switch y := b.(type) {
case nil:
return 1
case complex64:
if x == y {
return 0
}
if real(x) < real(y) {
return -1
}
if real(x) > real(y) {
return 1
}
if imag(x) < imag(y) {
return -1
}
return 1
case idealComplex:
{
x, y := x, complex64(y)
if x == y {
return 0
}
if real(x) < real(y) {
return -1
}
if real(x) > real(y) {
return 1
}
if imag(x) < imag(y) {
return -1
}
return 1
}
default:
panic("internal error 017")
}
case complex128:
switch y := b.(type) {
case nil:
return 1
case complex128:
if x == y {
return 0
}
if real(x) < real(y) {
return -1
}
if real(x) > real(y) {
return 1
}
if imag(x) < imag(y) {
return -1
}
return 1
case idealComplex:
{
x, y := x, complex128(y)
if x == y {
return 0
}
if real(x) < real(y) {
return -1
}
if real(x) > real(y) {
return 1
}
if imag(x) < imag(y) {
return -1
}
return 1
}
default:
panic("internal error 018")
}
case float32:
switch y := b.(type) {
case nil:
return 1
case float32:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealFloat:
{
x, y := x, float32(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 019")
}
case float64:
switch y := b.(type) {
case nil:
return 1
case float64:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealFloat:
{
x, y := x, float64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 020")
}
case int8:
switch y := b.(type) {
case nil:
return 1
case int8:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 021")
}
case int16:
switch y := b.(type) {
case nil:
return 1
case int16:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 022")
}
case int32:
switch y := b.(type) {
case nil:
return 1
case int32:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := int64(x), int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 023")
}
case int64:
switch y := b.(type) {
case nil:
return 1
case int64:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := x, int64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 024")
}
case uint8:
switch y := b.(type) {
case nil:
return 1
case uint8:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case idealUint:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 025")
}
case uint16:
switch y := b.(type) {
case nil:
return 1
case uint16:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case idealUint:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 026")
}
case uint32:
switch y := b.(type) {
case nil:
return 1
case uint32:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case idealUint:
{
x, y := uint64(x), uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 027")
}
case uint64:
switch y := b.(type) {
case nil:
return 1
case uint64:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
case idealInt:
{
x, y := x, uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
case idealUint:
{
x, y := x, uint64(y)
if x < y {
return -1
}
if x == y {
return 0
}
return 1
}
default:
panic("internal error 028")
}
case string:
switch y := b.(type) {
case nil:
return 1
case string:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
default:
panic("internal error 029")
}
case []byte:
switch y := b.(type) {
case nil:
return 1
case []byte:
return bytes.Compare(x, y)
default:
panic("internal error 030")
}
case *big.Int:
switch y := b.(type) {
case nil:
return 1
case *big.Int:
return x.Cmp(y)
case idealInt:
{
y := big.NewInt(int64(y))
return x.Cmp(y)
}
case idealUint:
{
u := big.NewInt(0)
u.SetUint64(uint64(y))
return x.Cmp(u)
}
default:
panic("internal error 031")
}
case *big.Rat:
switch y := b.(type) {
case nil:
return 1
case *big.Rat:
return x.Cmp(y)
case idealInt:
{
y := big.NewRat(int64(y), 1)
return x.Cmp(y)
}
case idealUint:
{
u := big.NewInt(0)
u.SetUint64(uint64(y))
var y big.Rat
y.SetInt(u)
return x.Cmp(&y)
}
default:
panic("internal error 032")
}
case time.Time:
switch y := b.(type) {
case nil:
return 1
case time.Time:
if x.Before(y) {
return -1
}
if x.Equal(y) {
return 0
}
return 1
default:
panic("internal error 033")
}
case time.Duration:
switch y := b.(type) {
case nil:
return 1
case time.Duration:
if x < y {
return -1
}
if x == y {
return 0
}
return 1
default:
panic("internal error 034")
}
case chunk:
switch y := b.(type) {
case nil:
return 1
case chunk:
a, err := x.expand()
if err != nil {
panic(err)
}
b, err := y.expand()
if err != nil {
panic(err)
}
return collate1(a, b)
default:
panic("internal error 035")
}
default:
//dbg("%T(%v) %T(%v)", a, a, b, b)
panic("internal error 036")
}
}
//TODO collate should return errors from collate1
func collate(x, y []interface{}) (r int) {
//defer func() { dbg("%v %v -> %v", x, y, r) }()
nx, ny := len(x), len(y)
switch {
case nx == 0 && ny != 0:
return -1
case nx == 0 && ny == 0:
return 0
case nx != 0 && ny == 0:
return 1
}
r = 1
if nx > ny {
x, y, r = y, x, -r
}
for i, xi := range x {
if c := collate1(xi, y[i]); c != 0 {
return c * r
}
}
if nx == ny {
return 0
}
return -r
}
var collators = map[bool]func(a, b []interface{}) int{false: collateDesc, true: collate}
func collateDesc(a, b []interface{}) int {
return -collate(a, b)
}
func isOrderedType(v interface{}) (y interface{}, r bool, err error) {
//dbg("====")
//dbg("%T(%v)", v, v)
//defer func() { dbg("%T(%v)", y, y) }()
switch x := v.(type) {
case idealFloat, idealInt, idealRune, idealUint,
float32, float64,
int8, int16, int32, int64,
uint8, uint16, uint32, uint64,
string:
return v, true, nil
case *big.Int, *big.Rat, time.Time, time.Duration:
return x, true, nil
case chunk:
if y, err = x.expand(); err != nil {
return
}
return isOrderedType(y)
}
return v, false, nil
}
var isSystemName = map[string]bool{
"__Column": true,
"__Column2": true,
"__Index": true,
"__Index2": true,
"__Index2_Column": true,
"__Index2_Expr": true,
"__Table": true,
}
func qnames(l []string) []string {
r := make([]string, len(l))
for i, v := range l {
r[i] = fmt.Sprintf("%q", v)
}
return r
}