func (e *NullSafeEquals) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 2 {
		return nil, sql.ErrInvalidChildrenNumber.New(e, len(children), 2)
	}
	return NewNullSafeEquals(children[0], children[1]), nil
}
WithChildren implements the Expression interface.
package expression
import (
	"fmt"
	"sync"
	errors "gopkg.in/src-d/go-errors.v1"
	"github.com/dolthub/go-mysql-server/internal/regex"
	"github.com/dolthub/go-mysql-server/sql"
)
var ErrInvalidRegexp = errors.NewKind("Invalid regular expression: %s")
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
}
func newComparison(left, right sql.Expression) comparison {
	return comparison{BinaryExpression{left, right}}
}
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 sql.TypesEqual(c.Left().Type(), c.Right().Type()) {
		return c.Left().Type().Compare(left, right)
	}
	var compareType sql.Type
	switch c.Left().(type) {
	case *GetField, *UserVar, *SystemVar, *ProcedureParam:
		compareType = c.Left().Type()
	default:
		switch c.Right().(type) {
		case *GetField, *UserVar, *SystemVar, *ProcedureParam:
			compareType = c.Right().Type()
		}
	}
	if compareType != nil {
		_, isEnum := compareType.(sql.EnumType)
		_, isSet := compareType.(sql.SetType)
		if !isEnum && !isSet {
			compareType = nil
		}
	}
	if compareType == nil {
		left, right, compareType, err = c.castLeftAndRight(left, right)
		if err != nil {
			return 0, err
		}
	}
	return 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{}, sql.Type, error) {
	leftType := c.Left().Type()
	rightType := c.Right().Type()
	if sql.IsTuple(leftType) && sql.IsTuple(rightType) {
		return left, right, c.Left().Type(), nil
	}
	if sql.IsNumber(leftType) || sql.IsNumber(rightType) {
		if sql.IsDecimal(leftType) || sql.IsDecimal(rightType) {
			l, r, err := convertLeftAndRight(left, right, ConvertToDecimal)
			if err != nil {
				return nil, nil, nil, err
			}
			if sql.IsDecimal(leftType) {
				return l, r, leftType, nil
			} else {
				return l, r, rightType, nil
			}
		}
		if sql.IsFloat(leftType) || sql.IsFloat(rightType) {
			l, r, err := convertLeftAndRight(left, right, ConvertToDouble)
			if err != nil {
				return nil, nil, nil, err
			}
			return l, r, sql.Float64, nil
		}
		if sql.IsSigned(leftType) || sql.IsSigned(rightType) {
			l, r, err := convertLeftAndRight(left, right, ConvertToSigned)
			if err != nil {
				return nil, nil, nil, err
			}
			return l, r, sql.Int64, nil
		}
		l, r, err := convertLeftAndRight(left, right, ConvertToUnsigned)
		if err != nil {
			return nil, nil, nil, err
		}
		return l, r, sql.Uint64, nil
	}
	if sql.IsTime(leftType) || sql.IsTime(rightType) {
		l, r, err := convertLeftAndRight(left, right, ConvertToDatetime)
		if err != nil {
			return nil, nil, nil, err
		}
		return l, r, sql.Datetime, nil
	}
	left, right, err := convertLeftAndRight(left, right, ConvertToChar)
	if err != nil {
		return nil, nil, nil, err
	}
	return left, right, sql.LongText, 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())
}
func (e *Equals) DebugString() string {
	return fmt.Sprintf("(%s = %s)", sql.DebugString(e.Left()), sql.DebugString(e.Right()))
}
type NullSafeEquals struct {
	comparison
}
func NewNullSafeEquals(left sql.Expression, right sql.Expression) *NullSafeEquals {
	return &NullSafeEquals{newComparison(left, right)}
}
func (e *NullSafeEquals) Type() sql.Type {
	return sql.Int8
}
func (e *NullSafeEquals) Compare(ctx *sql.Context, row sql.Row) (int, error) {
	left, right, err := e.evalLeftAndRight(ctx, row)
	if err != nil {
		return 0, err
	}
	if left == nil && right == nil {
		return 0, nil
	} else if left == nil {
		return 1, nil
	} else if right == nil {
		return -1, nil
	}
	if sql.TypesEqual(e.Left().Type(), e.Right().Type()) {
		return e.Left().Type().Compare(left, right)
	}
	var compareType sql.Type
	left, right, compareType, err = e.castLeftAndRight(left, right)
	if err != nil {
		return 0, err
	}
	return compareType.Compare(left, right)
}
func (e *NullSafeEquals) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	result, err := e.Compare(ctx, row)
	if err != nil {
		return nil, err
	}
	if result == 0 {
		return 1, nil
	}
	return 0, nil
}