func NewLessThan(left sql.Expression, right sql.Expression) *LessThan {
	return &LessThan{newComparison(left, right)}
}
NewLessThan creates a new LessThan expression.
package expression
import (
	"fmt"
	"sync"
	"github.com/src-d/go-mysql-server/internal/regex"
	"github.com/src-d/go-mysql-server/sql"
	errors "gopkg.in/src-d/go-errors.v1"
)
type Comparer interface {
	sql.Expression
	Compare(ctx *sql.Context, row sql.Row) (int, error)
	Left() sql.Expression
	Right() sql.Expression
}
var ErrNilOperand = errors.NewKind("nil operand found in comparison")
type comparison struct {
	BinaryExpression
	compareType sql.Type
}
func newComparison(left, right sql.Expression) comparison {
	return comparison{BinaryExpression{left, right}, nil}
}
func (c *comparison) Compare(ctx *sql.Context, row sql.Row) (int, error) {
	left, right, err := c.evalLeftAndRight(ctx, row)
	if err != nil {
		return 0, err
	}
	if left == nil || right == nil {
		return 0, ErrNilOperand.New()
	}
	if c.Left().Type() == c.Right().Type() {
		return c.Left().Type().Compare(left, right)
	}
	left, right, err = c.castLeftAndRight(left, right)
	if err != nil {
		return 0, err
	}
	return c.compareType.Compare(left, right)
}
func (c *comparison) evalLeftAndRight(ctx *sql.Context, row sql.Row) (interface{}, interface{}, error) {
	left, err := c.Left().Eval(ctx, row)
	if err != nil {
		return nil, nil, err
	}
	right, err := c.Right().Eval(ctx, row)
	if err != nil {
		return nil, nil, err
	}
	return left, right, nil
}
func (c *comparison) castLeftAndRight(left, right interface{}) (interface{}, interface{}, error) {
	if sql.IsNumber(c.Left().Type()) || sql.IsNumber(c.Right().Type()) {
		if sql.IsDecimal(c.Left().Type()) || sql.IsDecimal(c.Right().Type()) {
			l, r, err := convertLeftAndRight(left, right, ConvertToDecimal)
			if err != nil {
				return nil, nil, err
			}
			c.compareType = sql.Float64
			return l, r, nil
		}
		if sql.IsSigned(c.Left().Type()) || sql.IsSigned(c.Right().Type()) {
			l, r, err := convertLeftAndRight(left, right, ConvertToSigned)
			if err != nil {
				return nil, nil, err
			}
			c.compareType = sql.Int64
			return l, r, nil
		}
		l, r, err := convertLeftAndRight(left, right, ConvertToUnsigned)
		if err != nil {
			return nil, nil, err
		}
		c.compareType = sql.Uint64
		return l, r, nil
	}
	left, right, err := convertLeftAndRight(left, right, ConvertToChar)
	if err != nil {
		return nil, nil, err
	}
	c.compareType = sql.Text
	return left, right, nil
}
func convertLeftAndRight(left, right interface{}, convertTo string) (interface{}, interface{}, error) {
	l, err := convertValue(left, convertTo)
	if err != nil {
		return nil, nil, err
	}
	r, err := convertValue(right, convertTo)
	if err != nil {
		return nil, nil, err
	}
	return l, r, nil
}
func (*comparison) Type() sql.Type {
	return sql.Boolean
}
func (c *comparison) Left() sql.Expression { return c.BinaryExpression.Left }
func (c *comparison) Right() sql.Expression { return c.BinaryExpression.Right }
type Equals struct {
	comparison
}
func NewEquals(left sql.Expression, right sql.Expression) *Equals {
	return &Equals{newComparison(left, right)}
}
func (e *Equals) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	result, err := e.Compare(ctx, row)
	if err != nil {
		if ErrNilOperand.Is(err) {
			return nil, nil
		}
		return nil, err
	}
	return result == 0, nil
}
func (e *Equals) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 2 {
		return nil, sql.ErrInvalidChildrenNumber.New(e, len(children), 2)
	}
	return NewEquals(children[0], children[1]), nil
}
func (e *Equals) String() string {
	return fmt.Sprintf("%s = %s", e.Left(), e.Right())
}
type Regexp struct {
	comparison
	pool   *sync.Pool
	cached bool
}
func NewRegexp(left sql.Expression, right sql.Expression) *Regexp {
	var cached = true
	Inspect(right, func(e sql.Expression) bool {
		if _, ok := e.(*GetField); ok {
			cached = false
		}
		return true
	})
	return &Regexp{
		comparison: newComparison(left, right),
		pool:       nil,
		cached:     cached,
	}
}
func (re *Regexp) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	if sql.IsText(re.Left().Type()) && sql.IsText(re.Right().Type()) {
		return re.compareRegexp(ctx, row)
	}
	result, err := re.Compare(ctx, row)
	if err != nil {
		if ErrNilOperand.Is(err) {
			return nil, nil
		}
		return nil, err
	}
	return result == 0, nil
}
func (re *Regexp) compareRegexp(ctx *sql.Context, row sql.Row) (interface{}, error) {
	left, err := re.Left().Eval(ctx, row)
	if err != nil || left == nil {
		return nil, err
	}
	left, err = sql.Text.Convert(left)
	if err != nil {
		return nil, err
	}
	var (
		matcher  regex.Matcher
		disposer regex.Disposer
		right    interface{}
	)
	if !re.cached || re.pool == nil {
		right, err = re.Right().Eval(ctx, row)
		if err != nil || right == nil {
			return nil, err
		}
		right, err = sql.Text.Convert(right)
		if err != nil {
			return nil, err
		}
	}
	if !re.cached {
		matcher, disposer, err = regex.New(regex.Default(), right.(string))
	} else {
		if re.pool == nil {
			re.pool = &sync.Pool{
				New: func() interface{} {
					r, _, e := regex.New(regex.Default(), right.(string))
					if e != nil {
						err = e
						return nil
					}
					return r
				},
			}
		}
		if obj := re.pool.Get(); obj != nil {
			matcher = obj.(regex.Matcher)
		}
	}
	if matcher == nil {
		return nil, err
	}
	ok := matcher.Match(left.(string))
	if !re.cached {
		disposer.Dispose()
	} else if re.pool != nil {
		re.pool.Put(matcher)
	}
	return ok, nil
}
func (re *Regexp) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 2 {
		return nil, sql.ErrInvalidChildrenNumber.New(re, len(children), 2)
	}
	return NewRegexp(children[0], children[1]), nil
}
func (re *Regexp) String() string {
	return fmt.Sprintf("%s REGEXP %s", re.Left(), re.Right())
}
type GreaterThan struct {
	comparison
}
func NewGreaterThan(left sql.Expression, right sql.Expression) *GreaterThan {
	return &GreaterThan{newComparison(left, right)}
}
func (gt *GreaterThan) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	result, err := gt.Compare(ctx, row)
	if err != nil {
		if ErrNilOperand.Is(err) {
			return nil, nil
		}
		return nil, err
	}
	return result == 1, nil
}
func (gt *GreaterThan) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 2 {
		return nil, sql.ErrInvalidChildrenNumber.New(gt, len(children), 2)
	}
	return NewGreaterThan(children[0], children[1]), nil
}
func (gt *GreaterThan) String() string {
	return fmt.Sprintf("%s > %s", gt.Left(), gt.Right())
}
type LessThan struct {
	comparison
}