blob: b9fcce67875a3af7eebb06e8abb0a46c890f8cfa [file] [log] [blame]
// Copyright 2015 The Vanadium 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 conversions
import (
"errors"
"fmt"
"math/big"
"strconv"
"strings"
"v.io/syncbase/v23/syncbase/nosql/internal/query/query_parser"
)
func ConvertValueToString(o *query_parser.Operand) (*query_parser.Operand, error) {
var c query_parser.Operand
c.Type = query_parser.TypStr
c.Off = o.Off
switch o.Type {
case query_parser.TypBigInt:
c.Str = o.BigInt.String()
case query_parser.TypBigRat:
c.Str = o.BigRat.String()
case query_parser.TypBool:
c.Str = strconv.FormatBool(o.Bool)
case query_parser.TypComplex:
c.Str = fmt.Sprintf("%g", o.Complex)
case query_parser.TypFloat:
c.Str = strconv.FormatFloat(o.Float, 'f', -1, 64)
case query_parser.TypInt:
c.Str = strconv.FormatInt(o.Int, 10)
case query_parser.TypStr:
c.Str = o.Str
c.Regex = o.Regex // non-empty for rhs of like expressions
c.CompRegex = o.CompRegex // non-nil for rhs of like expressions
case query_parser.TypUint:
c.Str = strconv.FormatUint(o.Uint, 10)
case query_parser.TypObject:
return nil, errors.New("Cannot convert object to string.")
default:
// TODO(jkline): Log this logic error and all other similar cases.
return nil, errors.New("Cannot convert operand to string.")
}
return &c, nil
}
func ConvertValueToTime(o *query_parser.Operand) (*query_parser.Operand, error) {
switch o.Type {
case query_parser.TypTime:
return o, nil
default:
return nil, errors.New("Cannot convert operand to time.")
}
}
func ConvertValueToComplex(o *query_parser.Operand) (*query_parser.Operand, error) {
var c query_parser.Operand
c.Type = query_parser.TypComplex
switch o.Type {
case query_parser.TypComplex:
return o, nil
case query_parser.TypFloat:
c.Complex = complex(o.Float, 0.0i)
case query_parser.TypInt:
c.Complex = complex(float64(o.Int), 0.0i)
case query_parser.TypUint:
c.Complex = complex(float64(o.Uint), 0.0i)
default:
return nil, errors.New("Cannot convert operand to Complex.")
}
return &c, nil
}
func ConvertValueToBigRat(o *query_parser.Operand) (*query_parser.Operand, error) {
// operand cannot be string literal.
var c query_parser.Operand
c.Type = query_parser.TypBigRat
switch o.Type {
case query_parser.TypBigInt:
var b big.Rat
c.BigRat = b.SetInt(o.BigInt)
case query_parser.TypBigRat:
c.BigRat = o.BigRat
case query_parser.TypBool:
return nil, errors.New("Cannot convert bool to big.Rat.")
case query_parser.TypFloat:
var b big.Rat
c.BigRat = b.SetFloat64(o.Float)
case query_parser.TypInt:
c.BigRat = big.NewRat(o.Int, 1)
case query_parser.TypUint:
var bi big.Int
bi.SetUint64(o.Uint)
var br big.Rat
c.BigRat = br.SetInt(&bi)
case query_parser.TypObject:
return nil, errors.New("Cannot convert object to big.Rat.")
default:
// TODO(jkline): Log this logic error and all other similar cases.
return nil, errors.New("Cannot convert operand to big.Rat.")
}
return &c, nil
}
func ConvertValueToFloat(o *query_parser.Operand) (*query_parser.Operand, error) {
// Operand cannot be literal, big.Rat or big.Int
var c query_parser.Operand
c.Type = query_parser.TypFloat
switch o.Type {
case query_parser.TypBool:
return nil, errors.New("Cannot convert bool to float64.")
case query_parser.TypFloat:
c.Float = o.Float
case query_parser.TypInt:
c.Float = float64(o.Int)
case query_parser.TypUint:
c.Float = float64(o.Uint)
case query_parser.TypObject:
return nil, errors.New("Cannot convert object to float64.")
default:
// TODO(jkline): Log this logic error and all other similar cases.
return nil, errors.New("Cannot convert operand to float64.")
}
return &c, nil
}
func ConvertValueToBool(o *query_parser.Operand) (*query_parser.Operand, error) {
var c query_parser.Operand
c.Type = query_parser.TypBool
switch o.Type {
case query_parser.TypBool:
c.Bool = o.Bool
case query_parser.TypStr:
switch strings.ToLower(o.Str) {
case "true":
c.Bool = true
case "false":
c.Bool = false
default:
return nil, errors.New("Cannot convert object to bool.")
}
default:
return nil, errors.New("Cannot convert operand to bool.")
}
return &c, nil
}
func ConvertValueToBigInt(o *query_parser.Operand) (*query_parser.Operand, error) {
// Operand cannot be literal, big.Rat or float.
var c query_parser.Operand
c.Type = query_parser.TypBigInt
switch o.Type {
case query_parser.TypBigInt:
c.BigInt = o.BigInt
case query_parser.TypBool:
return nil, errors.New("Cannot convert bool to big.Int.")
case query_parser.TypInt:
c.BigInt = big.NewInt(o.Int)
case query_parser.TypUint:
var b big.Int
b.SetUint64(o.Uint)
c.BigInt = &b
case query_parser.TypObject:
return nil, errors.New("Cannot convert object to big.Int.")
default:
// TODO(jkline): Log this logic error and all other similar cases.
return nil, errors.New("Cannot convert operand to big.Int.")
}
return &c, nil
}
func ConvertValueToInt(o *query_parser.Operand) (*query_parser.Operand, error) {
// Operand cannot be literal, big.Rat or float or uint64.
var c query_parser.Operand
c.Type = query_parser.TypInt
switch o.Type {
case query_parser.TypBool:
return nil, errors.New("Cannot convert bool to int64.")
case query_parser.TypInt:
c.Int = o.Int
case query_parser.TypObject:
return nil, errors.New("Cannot convert object to int64.")
default:
// TODO(jkline): Log this logic error and all other similar cases.
return nil, errors.New("Cannot convert operand to int64.")
}
return &c, nil
}
func ConvertValueToUint(o *query_parser.Operand) (*query_parser.Operand, error) {
// Operand cannot be literal, big.Rat or float or int64.
var c query_parser.Operand
c.Type = query_parser.TypUint
switch o.Type {
case query_parser.TypBool:
return nil, errors.New("Cannot convert bool to int64.")
case query_parser.TypUint:
c.Uint = o.Uint
case query_parser.TypObject:
return nil, errors.New("Cannot convert object to int64.")
default:
// TODO(jkline): Log this logic error and all other similar cases.
return nil, errors.New("Cannot convert operand to int64.")
}
return &c, nil
}