func checkLikeExp(op BooleanOperation, lhs Expression, val interface{}, invert bool) BooleanExpression {
	rhs := val
	if t, ok := val.(*regexp.Regexp); ok {
		if op == LikeOp {
			op = RegexpLikeOp
		} else if op == ILikeOp {
			op = RegexpILikeOp
		}
		rhs = t.String()
	}
	if invert {
		op = operatorInversions[op]
	}
	return NewBooleanExpression(op, lhs, rhs)
}
checks an like rhs to create the proper like expression for strings or regexps
package exp
import (
	"reflect"
	"regexp"
)
type boolean struct {
	lhs Expression
	rhs interface{}
	op  BooleanOperation
}
func NewBooleanExpression(op BooleanOperation, lhs Expression, rhs interface{}) BooleanExpression {
	return boolean{op: op, lhs: lhs, rhs: rhs}
}
func (b boolean) Clone() Expression {
	return NewBooleanExpression(b.op, b.lhs.Clone(), b.rhs)
}
func (b boolean) Expression() Expression {
	return b
}
func (b boolean) RHS() interface{} {
	return b.rhs
}
func (b boolean) LHS() Expression {
	return b.lhs
}
func (b boolean) Op() BooleanOperation {
	return b.op
}
func (b boolean) As(val interface{}) AliasedExpression {
	return NewAliasExpression(b, val)
}
func eq(lhs Expression, rhs interface{}) BooleanExpression {
	return checkBoolExpType(EqOp, lhs, rhs, false)
}
func neq(lhs Expression, rhs interface{}) BooleanExpression {
	return checkBoolExpType(EqOp, lhs, rhs, true)
}
func gt(lhs Expression, rhs interface{}) BooleanExpression {
	return NewBooleanExpression(GtOp, lhs, rhs)
}
func gte(lhs Expression, rhs interface{}) BooleanExpression {
	return NewBooleanExpression(GteOp, lhs, rhs)
}
func lt(lhs Expression, rhs interface{}) BooleanExpression {
	return NewBooleanExpression(LtOp, lhs, rhs)
}
func lte(lhs Expression, rhs interface{}) BooleanExpression {
	return NewBooleanExpression(LteOp, lhs, rhs)
}
func in(lhs Expression, vals ...interface{}) BooleanExpression {
	if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
		return NewBooleanExpression(InOp, lhs, vals[0])
	}
	return NewBooleanExpression(InOp, lhs, vals)
}
func notIn(lhs Expression, vals ...interface{}) BooleanExpression {
	if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
		return NewBooleanExpression(NotInOp, lhs, vals[0])
	}
	return NewBooleanExpression(NotInOp, lhs, vals)
}
func is(lhs Expression, val interface{}) BooleanExpression {
	return checkBoolExpType(IsOp, lhs, val, false)
}
func isNot(lhs Expression, val interface{}) BooleanExpression {
	return checkBoolExpType(IsOp, lhs, val, true)
}
func like(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(LikeOp, lhs, val, false)
}
func iLike(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(ILikeOp, lhs, val, false)
}
func notLike(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(LikeOp, lhs, val, true)
}
func notILike(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(ILikeOp, lhs, val, true)
}
func regexpLike(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(RegexpLikeOp, lhs, val, false)
}
func regexpILike(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(RegexpILikeOp, lhs, val, false)
}
func regexpNotLike(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(RegexpLikeOp, lhs, val, true)
}
func regexpNotILike(lhs Expression, val interface{}) BooleanExpression {
	return checkLikeExp(RegexpILikeOp, lhs, val, true)
}