github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/evaluator/builtin_math.go (about)

     1  // Copyright 2013 The ql Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSES/QL-LICENSE file.
     4  
     5  // Copyright 2015 PingCAP, Inc.
     6  //
     7  // Licensed under the Apache License, Version 2.0 (the "License");
     8  // you may not use this file except in compliance with the License.
     9  // You may obtain a copy of the License at
    10  //
    11  //     http://www.apache.org/licenses/LICENSE-2.0
    12  //
    13  // Unless required by applicable law or agreed to in writing, software
    14  // distributed under the License is distributed on an "AS IS" BASIS,
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  package evaluator
    19  
    20  import (
    21  	"math"
    22  	"math/rand"
    23  
    24  	"github.com/insionng/yougam/libraries/juju/errors"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/types"
    27  )
    28  
    29  // see https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html
    30  
    31  func builtinAbs(args []types.Datum, _ context.Context) (d types.Datum, err error) {
    32  	d = args[0]
    33  	switch d.Kind() {
    34  	case types.KindNull:
    35  		return d, nil
    36  	case types.KindUint64:
    37  		return d, nil
    38  	case types.KindInt64:
    39  		iv := d.GetInt64()
    40  		if iv >= 0 {
    41  			d.SetInt64(iv)
    42  			return d, nil
    43  		}
    44  		d.SetInt64(-iv)
    45  		return d, nil
    46  	default:
    47  		// we will try to convert other types to float
    48  		// TODO: if time has no precision, it will be a integer
    49  		f, err := d.ToFloat64()
    50  		d.SetFloat64(math.Abs(f))
    51  		return d, errors.Trace(err)
    52  	}
    53  }
    54  
    55  func builtinRand(args []types.Datum, _ context.Context) (d types.Datum, err error) {
    56  	if len(args) == 1 && args[0].Kind() != types.KindNull {
    57  		seed, err := args[0].ToInt64()
    58  		if err != nil {
    59  			return d, errors.Trace(err)
    60  		}
    61  		rand.Seed(seed)
    62  	}
    63  	d.SetFloat64(rand.Float64())
    64  	return d, nil
    65  }
    66  
    67  func builtinPow(args []types.Datum, _ context.Context) (d types.Datum, err error) {
    68  	x, err := args[0].ToFloat64()
    69  	if err != nil {
    70  		return d, errors.Trace(err)
    71  	}
    72  
    73  	y, err := args[1].ToFloat64()
    74  	if err != nil {
    75  		return d, errors.Trace(err)
    76  	}
    77  	d.SetFloat64(math.Pow(x, y))
    78  	return d, nil
    79  }
    80  
    81  // See: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_round
    82  func builtinRound(args []types.Datum, _ context.Context) (d types.Datum, err error) {
    83  	x, err := args[0].ToFloat64()
    84  	if err != nil {
    85  		return d, errors.Trace(err)
    86  	}
    87  
    88  	dec := 0
    89  	if len(args) == 2 {
    90  		y, err1 := args[1].ToInt64()
    91  		if err1 != nil {
    92  			return d, errors.Trace(err1)
    93  		}
    94  		dec = int(y)
    95  	}
    96  	d.SetFloat64(types.Round(x, dec))
    97  	return d, nil
    98  }