func (a singleton) Join(other Lattice) (Lattice, error) {
	b, ok := other.(singleton)
	switch {
	case !ok:
		return nil, typeMismatchError(a, other)
	case a.value != b.value:
		return nil, distinctSingletonsErrors(a.value, b.value)
	default:
		return a, nil
	}
}
Join implements Lattice
package schemacmp
import (
	"fmt"
	"github.com/pingcap/tidb/parser/mysql"
	"github.com/pingcap/tidb/parser/types"
)
type IncompatibleError struct {
	Msg  string
	Args []interface{}
}
const (
	ErrMsgTypeMismatch           = "type mismatch (%T vs %T)"
	ErrMsgTupleLengthMismatch    = "tuple length mismatch (%d vs %d)"
	ErrMsgDistinctSingletons     = "distinct singletons (%v vs %v)"
	ErrMsgIncompatibleType       = "incompatible mysql type (%v vs %v)"
	ErrMsgAtTupleIndex           = "at tuple index %d: %v"
	ErrMsgAtMapKey               = "at map key %q: %v"
	ErrMsgNonInclusiveBitSets    = "non-inclusive bit sets (%#x vs %#x)"
	ErrMsgContradictingOrders    = "combining contradicting orders (%d && %d)"
	ErrMsgStringListElemMismatch = "at string list index %d: distinct values (%q vs %q)"
)
func (e *IncompatibleError) Error() string {
	return fmt.Sprintf(e.Msg, e.Args...)
}
func typeMismatchError(a, b Lattice) *IncompatibleError {
	return &IncompatibleError{
		Msg:  ErrMsgTypeMismatch,
		Args: []interface{}{a, b},
	}
}
func tupleLengthMismatchError(a, b int) *IncompatibleError {
	return &IncompatibleError{
		Msg:  ErrMsgTupleLengthMismatch,
		Args: []interface{}{a, b},
	}
}
func distinctSingletonsErrors(a, b interface{}) *IncompatibleError {
	return &IncompatibleError{
		Msg:  ErrMsgDistinctSingletons,
		Args: []interface{}{a, b},
	}
}
func incompatibleTypeError(a, b interface{}) *IncompatibleError {
	return &IncompatibleError{
		Msg:  ErrMsgIncompatibleType,
		Args: []interface{}{a, b},
	}
}
func wrapTupleIndexError(i int, inner error) *IncompatibleError {
	return &IncompatibleError{
		Msg:  ErrMsgAtTupleIndex,
		Args: []interface{}{i, inner},
	}
}
func wrapMapKeyError(key string, inner error) *IncompatibleError {
	return &IncompatibleError{
		Msg:  ErrMsgAtMapKey,
		Args: []interface{}{key, inner},
	}
}
type Lattice interface {
	Unwrap() interface{}
	Compare(other Lattice) (int, error)
	Join(other Lattice) (Lattice, error)
}
type Bool bool
func (a Bool) Unwrap() interface{} {
	return bool(a)
}
func (a Bool) Compare(other Lattice) (int, error) {
	b, ok := other.(Bool)
	switch {
	case !ok:
		return 0, typeMismatchError(a, other)
	case a == b:
		return 0, nil
	case bool(a):
		return 1, nil
	default:
		return -1, nil
	}
}
func (a Bool) Join(other Lattice) (Lattice, error) {
	b, ok := other.(Bool)
	if !ok {
		return nil, typeMismatchError(a, other)
	}
	return a || b, nil
}
type singleton struct{ value interface{} }
func (a singleton) Unwrap() interface{} {
	return a.value
}
func Singleton(value interface{}) Lattice {
	return singleton{value: value}
}
func (a singleton) Compare(other Lattice) (int, error) {
	b, ok := other.(singleton)
	switch {
	case !ok:
		return 0, typeMismatchError(a, other)
	case a.value != b.value:
		return 0, distinctSingletonsErrors(a.value, b.value)
	default:
		return 0, nil
	}
}