func (l *Log) Children() []sql.Expression {
	return []sql.Expression{l.Left, l.Right}
}
Children implements the Expression interface.
package function
import (
	"fmt"
	"math"
	"reflect"
	"github.com/src-d/go-mysql-server/sql"
	"github.com/src-d/go-mysql-server/sql/expression"
	"gopkg.in/src-d/go-errors.v1"
)
var ErrInvalidArgumentForLogarithm = errors.NewKind("invalid argument value for logarithm: %v")
func NewLogBaseFunc(base float64) func(e sql.Expression) sql.Expression {
	return func(e sql.Expression) sql.Expression {
		return NewLogBase(base, e)
	}
}
type LogBase struct {
	expression.UnaryExpression
	base float64
}
func NewLogBase(base float64, e sql.Expression) sql.Expression {
	return &LogBase{UnaryExpression: expression.UnaryExpression{Child: e}, base: base}
}
func (l *LogBase) String() string {
	switch l.base {
	case float64(math.E):
		return fmt.Sprintf("ln(%s)", l.Child)
	case float64(10):
		return fmt.Sprintf("log10(%s)", l.Child)
	case float64(2):
		return fmt.Sprintf("log2(%s)", l.Child)
	default:
		return fmt.Sprintf("log(%v, %s)", l.base, l.Child)
	}
}
func (l *LogBase) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(l, len(children), 1)
	}
	return NewLogBase(l.base, children[0]), nil
}
func (l *LogBase) Type() sql.Type {
	return sql.Float64
}
func (l *LogBase) IsNullable() bool {
	return l.base == float64(1) || l.base <= float64(0) || l.Child.IsNullable()
}
func (l *LogBase) Eval(
	ctx *sql.Context,
	row sql.Row,
) (interface{}, error) {
	v, err := l.Child.Eval(ctx, row)
	if err != nil {
		return nil, err
	}
	if v == nil {
		return nil, nil
	}
	val, err := sql.Float64.Convert(v)
	if err != nil {
		return nil, sql.ErrInvalidType.New(reflect.TypeOf(v))
	}
	return computeLog(val.(float64), l.base)
}
type Log struct {
	expression.BinaryExpression
}
func NewLog(args ...sql.Expression) (sql.Expression, error) {
	argLen := len(args)
	if argLen == 0 || argLen > 2 {
		return nil, sql.ErrInvalidArgumentNumber.New("LOG", "1 or 2", argLen)
	}
	if argLen == 1 {
		return &Log{expression.BinaryExpression{Left: expression.NewLiteral(math.E, sql.Float64), Right: args[0]}}, nil
	} else {
		return &Log{expression.BinaryExpression{Left: args[0], Right: args[1]}}, nil
	}
}
func (l *Log) String() string {
	return fmt.Sprintf("log(%s, %s)", l.Left, l.Right)
}
func (l *Log) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	return NewLog(children...)
}