github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/comparison.go (about)

     1  // Copyright 2020-2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package expression
    16  
    17  import (
    18  	"fmt"
    19  	"sync"
    20  
    21  	errors "gopkg.in/src-d/go-errors.v1"
    22  
    23  	"github.com/dolthub/go-mysql-server/internal/regex"
    24  	"github.com/dolthub/go-mysql-server/sql"
    25  	"github.com/dolthub/go-mysql-server/sql/types"
    26  )
    27  
    28  var ErrInvalidRegexp = errors.NewKind("Invalid regular expression: %s")
    29  
    30  // Comparer implements a comparison expression.
    31  type Comparer interface {
    32  	sql.Expression
    33  	Compare(ctx *sql.Context, row sql.Row) (int, error)
    34  	Left() sql.Expression
    35  	Right() sql.Expression
    36  }
    37  
    38  // ErrNilOperand ir returned if some or both of the comparison's operands is nil.
    39  var ErrNilOperand = errors.NewKind("nil operand found in comparison")
    40  
    41  // PreciseComparison searches an expression tree for comparison
    42  // expressions that require a conversion or type promotion.
    43  // This utility helps determine if filter predicates can be pushed down.
    44  func PreciseComparison(e sql.Expression) bool {
    45  	var imprecise bool
    46  	sql.Inspect(e, func(expr sql.Expression) bool {
    47  		if cmp, ok := expr.(Comparer); ok {
    48  			left, right := cmp.Left().Type(), cmp.Right().Type()
    49  
    50  			// integer comparisons are exact
    51  			if types.IsInteger(left) && types.IsInteger(right) {
    52  				return true
    53  			}
    54  
    55  			// comparisons with type conversions are sometimes imprecise
    56  			if !left.Equals(right) {
    57  				imprecise = true
    58  				return false
    59  			}
    60  		}
    61  		return true
    62  	})
    63  	return !imprecise
    64  }
    65  
    66  type comparison struct {
    67  	BinaryExpressionStub
    68  }
    69  
    70  // disableRounding disables rounding for the given expression.
    71  func disableRounding(expr sql.Expression) {
    72  	setArithmeticOps(expr, -1)
    73  	setDivOps(expr, -1)
    74  }
    75  
    76  func newComparison(left, right sql.Expression) comparison {
    77  	disableRounding(left)
    78  	disableRounding(right)
    79  	return comparison{BinaryExpressionStub{left, right}}
    80  }
    81  
    82  // CollationCoercibility implements the interface sql.CollationCoercible.
    83  func (c *comparison) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
    84  	leftCollation, leftCoercibility := sql.GetCoercibility(ctx, c.Left())
    85  	rightCollation, rightCoercibility := sql.GetCoercibility(ctx, c.Right())
    86  	return sql.ResolveCoercibility(leftCollation, leftCoercibility, rightCollation, rightCoercibility)
    87  }
    88  
    89  // Compare the two given values using the types of the expressions in the comparison.
    90  // Since both types should be equal, it does not matter which type is used, but for
    91  // reference, the left type is always used.
    92  func (c *comparison) Compare(ctx *sql.Context, row sql.Row) (int, error) {
    93  	left, right, err := c.evalLeftAndRight(ctx, row)
    94  	if err != nil {
    95  		return 0, err
    96  	}
    97  
    98  	if left == nil || right == nil {
    99  		return 0, ErrNilOperand.New()
   100  	}
   101  
   102  	if types.TypesEqual(c.Left().Type(), c.Right().Type()) {
   103  		return c.Left().Type().Compare(left, right)
   104  	}
   105  
   106  	// ENUM, SET, and TIME must be excluded when doing comparisons, as they're too restrictive to use as a comparison
   107  	// base.
   108  	//
   109  	// The best overall method would be to assign type priority. For example, INT would have a higher priority than
   110  	// TINYINT. This could then be combined with the origin of the value (table column, procedure param, etc.) to
   111  	// determine the best type for any comparison (tie-breakers can be simple rules such as the current left preference).
   112  	var compareType sql.Type
   113  	collationPreference := sql.Collation_Default
   114  	switch c.Left().(type) {
   115  	case *GetField, *UserVar, *SystemVar, *ProcedureParam:
   116  		compareType = c.Left().Type()
   117  		if twc, ok := compareType.(sql.TypeWithCollation); ok {
   118  			collationPreference = twc.Collation()
   119  		}
   120  	default:
   121  		switch c.Right().(type) {
   122  		case *GetField, *UserVar, *SystemVar, *ProcedureParam:
   123  			compareType = c.Right().Type()
   124  			if twc, ok := compareType.(sql.TypeWithCollation); ok {
   125  				collationPreference = twc.Collation()
   126  			}
   127  		}
   128  	}
   129  	if compareType != nil {
   130  		_, isEnum := compareType.(sql.EnumType)
   131  		_, isSet := compareType.(sql.SetType)
   132  		_, isTime := compareType.(types.TimeType)
   133  		if !isEnum && !isSet && !isTime {
   134  			compareType = nil
   135  		}
   136  	}
   137  	if compareType == nil {
   138  		left, right, compareType, err = c.castLeftAndRight(left, right)
   139  		if err != nil {
   140  			return 0, err
   141  		}
   142  	}
   143  	if types.IsTextOnly(compareType) {
   144  		collationPreference, _ = c.CollationCoercibility(ctx)
   145  		if err != nil {
   146  			return 0, err
   147  		}
   148  		stringCompareType := compareType.(sql.StringType)
   149  		compareType = types.MustCreateString(stringCompareType.Type(), stringCompareType.Length(), collationPreference)
   150  	}
   151  
   152  	return compareType.Compare(left, right)
   153  }
   154  
   155  func (c *comparison) evalLeftAndRight(ctx *sql.Context, row sql.Row) (interface{}, interface{}, error) {
   156  	left, err := c.Left().Eval(ctx, row)
   157  	if err != nil {
   158  		return nil, nil, err
   159  	}
   160  
   161  	right, err := c.Right().Eval(ctx, row)
   162  	if err != nil {
   163  		return nil, nil, err
   164  	}
   165  
   166  	return left, right, nil
   167  }
   168  
   169  func (c *comparison) castLeftAndRight(left, right interface{}) (interface{}, interface{}, sql.Type, error) {
   170  	leftType := c.Left().Type()
   171  	rightType := c.Right().Type()
   172  	if types.IsTuple(leftType) && types.IsTuple(rightType) {
   173  		return left, right, c.Left().Type(), nil
   174  	}
   175  
   176  	if types.IsTime(leftType) || types.IsTime(rightType) {
   177  		l, r, err := convertLeftAndRight(left, right, ConvertToDatetime)
   178  		if err != nil {
   179  			return nil, nil, nil, err
   180  		}
   181  
   182  		return l, r, types.DatetimeMaxPrecision, nil
   183  	}
   184  
   185  	// Rely on types.JSON.Compare to handle JSON comparisons
   186  	if types.IsJSON(leftType) || types.IsJSON(rightType) {
   187  		return left, right, types.JSON, nil
   188  	}
   189  
   190  	if types.IsBinaryType(leftType) || types.IsBinaryType(rightType) {
   191  		l, r, err := convertLeftAndRight(left, right, ConvertToBinary)
   192  		if err != nil {
   193  			return nil, nil, nil, err
   194  		}
   195  		return l, r, types.LongBlob, nil
   196  	}
   197  
   198  	if types.IsNumber(leftType) || types.IsNumber(rightType) {
   199  		if types.IsDecimal(leftType) || types.IsDecimal(rightType) {
   200  			//TODO: We need to set to the actual DECIMAL type
   201  			l, r, err := convertLeftAndRight(left, right, ConvertToDecimal)
   202  			if err != nil {
   203  				return nil, nil, nil, err
   204  			}
   205  
   206  			if types.IsDecimal(leftType) {
   207  				return l, r, leftType, nil
   208  			} else {
   209  				return l, r, rightType, nil
   210  			}
   211  		}
   212  
   213  		if types.IsFloat(leftType) || types.IsFloat(rightType) {
   214  			l, r, err := convertLeftAndRight(left, right, ConvertToDouble)
   215  			if err != nil {
   216  				return nil, nil, nil, err
   217  			}
   218  
   219  			return l, r, types.Float64, nil
   220  		}
   221  
   222  		if types.IsSigned(leftType) && types.IsSigned(rightType) {
   223  			l, r, err := convertLeftAndRight(left, right, ConvertToSigned)
   224  			if err != nil {
   225  				return nil, nil, nil, err
   226  			}
   227  
   228  			return l, r, types.Int64, nil
   229  		}
   230  
   231  		if types.IsUnsigned(leftType) && types.IsUnsigned(rightType) {
   232  			l, r, err := convertLeftAndRight(left, right, ConvertToUnsigned)
   233  			if err != nil {
   234  				return nil, nil, nil, err
   235  			}
   236  
   237  			return l, r, types.Uint64, nil
   238  		}
   239  
   240  		l, r, err := convertLeftAndRight(left, right, ConvertToDouble)
   241  		if err != nil {
   242  			return nil, nil, nil, err
   243  		}
   244  
   245  		return l, r, types.Float64, nil
   246  	}
   247  
   248  	left, right, err := convertLeftAndRight(left, right, ConvertToChar)
   249  	if err != nil {
   250  		return nil, nil, nil, err
   251  	}
   252  
   253  	return left, right, types.LongText, nil
   254  }
   255  
   256  func convertLeftAndRight(left, right interface{}, convertTo string) (interface{}, interface{}, error) {
   257  	l, err := convertValue(left, convertTo, nil, 0, 0)
   258  	if err != nil {
   259  		return nil, nil, err
   260  	}
   261  
   262  	r, err := convertValue(right, convertTo, nil, 0, 0)
   263  	if err != nil {
   264  		return nil, nil, err
   265  	}
   266  
   267  	return l, r, nil
   268  }
   269  
   270  // Type implements the Expression interface.
   271  func (*comparison) Type() sql.Type {
   272  	return types.Boolean
   273  }
   274  
   275  // Left implements Comparer interface
   276  func (c *comparison) Left() sql.Expression { return c.BinaryExpressionStub.LeftChild }
   277  
   278  // Right implements Comparer interface
   279  func (c *comparison) Right() sql.Expression { return c.BinaryExpressionStub.RightChild }
   280  
   281  // Equals is a comparison that checks an expression is equal to another.
   282  type Equals struct {
   283  	comparison
   284  }
   285  
   286  var _ sql.Expression = (*Equals)(nil)
   287  var _ sql.CollationCoercible = (*Equals)(nil)
   288  
   289  // NewEquals returns a new Equals expression.
   290  func NewEquals(left sql.Expression, right sql.Expression) *Equals {
   291  	return &Equals{newComparison(left, right)}
   292  }
   293  
   294  // CollationCoercibility implements the interface sql.CollationCoercible.
   295  func (e *Equals) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   296  	return sql.Collation_binary, 5
   297  }
   298  
   299  // Eval implements the Expression interface.
   300  func (e *Equals) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
   301  	result, err := e.Compare(ctx, row)
   302  	if err != nil {
   303  		if ErrNilOperand.Is(err) {
   304  			return nil, nil
   305  		}
   306  
   307  		return nil, err
   308  	}
   309  
   310  	return result == 0, nil
   311  }
   312  
   313  // WithChildren implements the Expression interface.
   314  func (e *Equals) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   315  	if len(children) != 2 {
   316  		return nil, sql.ErrInvalidChildrenNumber.New(e, len(children), 2)
   317  	}
   318  	return NewEquals(children[0], children[1]), nil
   319  }
   320  
   321  func (e *Equals) String() string {
   322  	if e == nil {
   323  		return ""
   324  	}
   325  	return fmt.Sprintf("(%s = %s)", e.Left(), e.Right())
   326  }
   327  
   328  func (e *Equals) DebugString() string {
   329  	if e == nil {
   330  		return ""
   331  	}
   332  	pr := sql.NewTreePrinter()
   333  	_ = pr.WriteNode("Eq")
   334  	children := []string{sql.DebugString(e.Left()), sql.DebugString(e.Right())}
   335  	_ = pr.WriteChildren(children...)
   336  	return pr.String()
   337  }
   338  
   339  // NullSafeEquals is a comparison that checks an expression is equal to
   340  // another, where NULLs do not coalesce to NULL and two NULLs compare equal to
   341  // each other.
   342  type NullSafeEquals struct {
   343  	comparison
   344  }
   345  
   346  var _ sql.Expression = (*NullSafeEquals)(nil)
   347  var _ sql.CollationCoercible = (*NullSafeEquals)(nil)
   348  
   349  // NewNullSafeEquals returns a new NullSafeEquals expression.
   350  func NewNullSafeEquals(left sql.Expression, right sql.Expression) *NullSafeEquals {
   351  	return &NullSafeEquals{newComparison(left, right)}
   352  }
   353  
   354  // Type implements the Expression interface.
   355  func (e *NullSafeEquals) Type() sql.Type {
   356  	return types.Boolean
   357  }
   358  
   359  // CollationCoercibility implements the interface sql.CollationCoercible.
   360  func (e *NullSafeEquals) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   361  	return sql.Collation_binary, 5
   362  }
   363  
   364  func (e *NullSafeEquals) Compare(ctx *sql.Context, row sql.Row) (int, error) {
   365  	left, right, err := e.evalLeftAndRight(ctx, row)
   366  	if err != nil {
   367  		return 0, err
   368  	}
   369  
   370  	if left == nil && right == nil {
   371  		return 0, nil
   372  	} else if left == nil {
   373  		return 1, nil
   374  	} else if right == nil {
   375  		return -1, nil
   376  	}
   377  
   378  	if types.TypesEqual(e.Left().Type(), e.Right().Type()) {
   379  		return e.Left().Type().Compare(left, right)
   380  	}
   381  
   382  	var compareType sql.Type
   383  	left, right, compareType, err = e.castLeftAndRight(left, right)
   384  	if err != nil {
   385  		return 0, err
   386  	}
   387  
   388  	return compareType.Compare(left, right)
   389  }
   390  
   391  // Eval implements the Expression interface.
   392  func (e *NullSafeEquals) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
   393  	result, err := e.Compare(ctx, row)
   394  	if err != nil {
   395  		return nil, err
   396  	}
   397  
   398  	return result == 0, nil
   399  }
   400  
   401  // WithChildren implements the Expression interface.
   402  func (e *NullSafeEquals) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   403  	if len(children) != 2 {
   404  		return nil, sql.ErrInvalidChildrenNumber.New(e, len(children), 2)
   405  	}
   406  	return NewNullSafeEquals(children[0], children[1]), nil
   407  }
   408  
   409  func (e *NullSafeEquals) String() string {
   410  	return fmt.Sprintf("(%s <=> %s)", e.Left(), e.Right())
   411  }
   412  
   413  func (e *NullSafeEquals) DebugString() string {
   414  	return fmt.Sprintf("(%s <=> %s)", sql.DebugString(e.Left()), sql.DebugString(e.Right()))
   415  }
   416  
   417  // Regexp is a comparison that checks an expression matches a regexp.
   418  type Regexp struct {
   419  	comparison
   420  	pool   *sync.Pool
   421  	cached bool
   422  	once   sync.Once
   423  }
   424  
   425  var _ sql.Expression = (*Regexp)(nil)
   426  var _ sql.CollationCoercible = (*Regexp)(nil)
   427  
   428  // NewRegexp creates a new Regexp expression.
   429  func NewRegexp(left sql.Expression, right sql.Expression) *Regexp {
   430  	var cached = true
   431  	sql.Inspect(right, func(e sql.Expression) bool {
   432  		if _, ok := e.(*GetField); ok {
   433  			cached = false
   434  		}
   435  		return true
   436  	})
   437  
   438  	return &Regexp{
   439  		comparison: newComparison(left, right),
   440  		pool:       nil,
   441  		cached:     cached,
   442  		once:       sync.Once{},
   443  	}
   444  }
   445  
   446  // Eval implements the Expression interface.
   447  func (re *Regexp) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
   448  	if types.IsText(re.Right().Type()) {
   449  		return re.compareRegexp(ctx, row)
   450  	}
   451  
   452  	result, err := re.Compare(ctx, row)
   453  	if err != nil {
   454  		if ErrNilOperand.Is(err) {
   455  			return nil, nil
   456  		}
   457  
   458  		return nil, err
   459  	}
   460  
   461  	return result == 0, nil
   462  }
   463  
   464  type matcherErrTuple struct {
   465  	matcher regex.DisposableMatcher
   466  	err     error
   467  }
   468  
   469  func (re *Regexp) compareRegexp(ctx *sql.Context, row sql.Row) (interface{}, error) {
   470  	left, err := re.Left().Eval(ctx, row)
   471  	if err != nil || left == nil {
   472  		return nil, err
   473  	}
   474  	left, _, err = types.LongText.Convert(left)
   475  	if err != nil {
   476  		return nil, err
   477  	}
   478  
   479  	var matcher regex.DisposableMatcher
   480  
   481  	if !re.cached {
   482  		right, rerr := re.evalRight(ctx, row)
   483  		if rerr != nil || right == nil {
   484  			return right, rerr
   485  		}
   486  		matcher, err = regex.NewDisposableMatcher(regex.Default(), *right)
   487  	} else {
   488  		re.once.Do(func() {
   489  			right, err := re.evalRight(ctx, row)
   490  			re.pool = &sync.Pool{
   491  				New: func() interface{} {
   492  					if err != nil || right == nil {
   493  						return matcherErrTuple{nil, err}
   494  					}
   495  					m, e := regex.NewDisposableMatcher(regex.Default(), *right)
   496  					return matcherErrTuple{m, e}
   497  				},
   498  			}
   499  		})
   500  		met := re.pool.Get().(matcherErrTuple)
   501  		matcher, err = met.matcher, met.err
   502  	}
   503  
   504  	if err != nil {
   505  		return nil, ErrInvalidRegexp.New(err.Error())
   506  	} else if matcher == nil {
   507  		return nil, nil
   508  	}
   509  
   510  	ok := matcher.Match(left.(string))
   511  
   512  	if !re.cached {
   513  		matcher.Dispose()
   514  	} else {
   515  		re.pool.Put(matcherErrTuple{matcher, nil})
   516  	}
   517  	return ok, nil
   518  }
   519  
   520  func (re *Regexp) evalRight(ctx *sql.Context, row sql.Row) (*string, error) {
   521  	right, err := re.Right().Eval(ctx, row)
   522  	if err != nil {
   523  		return nil, err
   524  	}
   525  	if right == nil {
   526  		return nil, nil
   527  	}
   528  	right, _, err = types.LongText.Convert(right)
   529  	if err != nil {
   530  		return nil, err
   531  	}
   532  	s := right.(string)
   533  	return &s, nil
   534  }
   535  
   536  // WithChildren implements the Expression interface.
   537  func (re *Regexp) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   538  	if len(children) != 2 {
   539  		return nil, sql.ErrInvalidChildrenNumber.New(re, len(children), 2)
   540  	}
   541  	return NewRegexp(children[0], children[1]), nil
   542  }
   543  
   544  func (re *Regexp) String() string {
   545  	return fmt.Sprintf("(%s REGEXP %s)", re.Left(), re.Right())
   546  }
   547  
   548  func (re *Regexp) DebugString() string {
   549  	return fmt.Sprintf("(%s REGEXP %s)", sql.DebugString(re.Left()), sql.DebugString(re.Right()))
   550  }
   551  
   552  // GreaterThan is a comparison that checks an expression is greater than another.
   553  type GreaterThan struct {
   554  	comparison
   555  }
   556  
   557  var _ sql.Expression = (*GreaterThan)(nil)
   558  var _ sql.CollationCoercible = (*GreaterThan)(nil)
   559  
   560  // NewGreaterThan creates a new GreaterThan expression.
   561  func NewGreaterThan(left sql.Expression, right sql.Expression) *GreaterThan {
   562  	return &GreaterThan{newComparison(left, right)}
   563  }
   564  
   565  // CollationCoercibility implements the interface sql.CollationCoercible.
   566  func (gt *GreaterThan) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   567  	return sql.Collation_binary, 5
   568  }
   569  
   570  // Eval implements the Expression interface.
   571  func (gt *GreaterThan) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
   572  	result, err := gt.Compare(ctx, row)
   573  	if err != nil {
   574  		if ErrNilOperand.Is(err) {
   575  			return nil, nil
   576  		}
   577  
   578  		return nil, err
   579  	}
   580  
   581  	return result == 1, nil
   582  }
   583  
   584  // WithChildren implements the Expression interface.
   585  func (gt *GreaterThan) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   586  	if len(children) != 2 {
   587  		return nil, sql.ErrInvalidChildrenNumber.New(gt, len(children), 2)
   588  	}
   589  	return NewGreaterThan(children[0], children[1]), nil
   590  }
   591  
   592  func (gt *GreaterThan) String() string {
   593  	return fmt.Sprintf("(%s > %s)", gt.Left(), gt.Right())
   594  }
   595  
   596  func (gt *GreaterThan) DebugString() string {
   597  	pr := sql.NewTreePrinter()
   598  	_ = pr.WriteNode("GreaterThan")
   599  	children := []string{sql.DebugString(gt.Left()), sql.DebugString(gt.Right())}
   600  	_ = pr.WriteChildren(children...)
   601  	return pr.String()
   602  }
   603  
   604  // LessThan is a comparison that checks an expression is less than another.
   605  type LessThan struct {
   606  	comparison
   607  }
   608  
   609  var _ sql.Expression = (*LessThan)(nil)
   610  var _ sql.CollationCoercible = (*LessThan)(nil)
   611  
   612  // NewLessThan creates a new LessThan expression.
   613  func NewLessThan(left sql.Expression, right sql.Expression) *LessThan {
   614  	return &LessThan{newComparison(left, right)}
   615  }
   616  
   617  // CollationCoercibility implements the interface sql.CollationCoercible.
   618  func (lt *LessThan) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   619  	return sql.Collation_binary, 5
   620  }
   621  
   622  // Eval implements the expression interface.
   623  func (lt *LessThan) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
   624  	result, err := lt.Compare(ctx, row)
   625  	if err != nil {
   626  		if ErrNilOperand.Is(err) {
   627  			return nil, nil
   628  		}
   629  
   630  		return nil, err
   631  	}
   632  
   633  	return result == -1, nil
   634  }
   635  
   636  // WithChildren implements the Expression interface.
   637  func (lt *LessThan) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   638  	if len(children) != 2 {
   639  		return nil, sql.ErrInvalidChildrenNumber.New(lt, len(children), 2)
   640  	}
   641  	return NewLessThan(children[0], children[1]), nil
   642  }
   643  
   644  func (lt *LessThan) String() string {
   645  	return fmt.Sprintf("(%s < %s)", lt.Left(), lt.Right())
   646  }
   647  
   648  func (lt *LessThan) DebugString() string {
   649  	pr := sql.NewTreePrinter()
   650  	_ = pr.WriteNode("LessThan")
   651  	children := []string{sql.DebugString(lt.Left()), sql.DebugString(lt.Right())}
   652  	_ = pr.WriteChildren(children...)
   653  	return pr.String()
   654  }
   655  
   656  // GreaterThanOrEqual is a comparison that checks an expression is greater or equal to
   657  // another.
   658  type GreaterThanOrEqual struct {
   659  	comparison
   660  }
   661  
   662  var _ sql.Expression = (*GreaterThanOrEqual)(nil)
   663  var _ sql.CollationCoercible = (*GreaterThanOrEqual)(nil)
   664  
   665  // NewGreaterThanOrEqual creates a new GreaterThanOrEqual
   666  func NewGreaterThanOrEqual(left sql.Expression, right sql.Expression) *GreaterThanOrEqual {
   667  	return &GreaterThanOrEqual{newComparison(left, right)}
   668  }
   669  
   670  // CollationCoercibility implements the interface sql.CollationCoercible.
   671  func (gte *GreaterThanOrEqual) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   672  	return sql.Collation_binary, 5
   673  }
   674  
   675  // Eval implements the Expression interface.
   676  func (gte *GreaterThanOrEqual) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
   677  	result, err := gte.Compare(ctx, row)
   678  	if err != nil {
   679  		if ErrNilOperand.Is(err) {
   680  			return nil, nil
   681  		}
   682  
   683  		return nil, err
   684  	}
   685  
   686  	return result > -1, nil
   687  }
   688  
   689  // WithChildren implements the Expression interface.
   690  func (gte *GreaterThanOrEqual) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   691  	if len(children) != 2 {
   692  		return nil, sql.ErrInvalidChildrenNumber.New(gte, len(children), 2)
   693  	}
   694  	return NewGreaterThanOrEqual(children[0], children[1]), nil
   695  }
   696  
   697  func (gte *GreaterThanOrEqual) String() string {
   698  	return fmt.Sprintf("(%s >= %s)", gte.Left(), gte.Right())
   699  }
   700  
   701  func (gte *GreaterThanOrEqual) DebugString() string {
   702  	pr := sql.NewTreePrinter()
   703  	_ = pr.WriteNode("GreaterThanOrEqual")
   704  	children := []string{sql.DebugString(gte.Left()), sql.DebugString(gte.Right())}
   705  	_ = pr.WriteChildren(children...)
   706  	return pr.String()
   707  }
   708  
   709  // LessThanOrEqual is a comparison that checks an expression is equal or lower than
   710  // another.
   711  type LessThanOrEqual struct {
   712  	comparison
   713  }
   714  
   715  var _ sql.Expression = (*LessThanOrEqual)(nil)
   716  var _ sql.CollationCoercible = (*LessThanOrEqual)(nil)
   717  
   718  // NewLessThanOrEqual creates a LessThanOrEqual expression.
   719  func NewLessThanOrEqual(left sql.Expression, right sql.Expression) *LessThanOrEqual {
   720  	return &LessThanOrEqual{newComparison(left, right)}
   721  }
   722  
   723  // CollationCoercibility implements the interface sql.CollationCoercible.
   724  func (lte *LessThanOrEqual) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   725  	return sql.Collation_binary, 5
   726  }
   727  
   728  // Eval implements the Expression interface.
   729  func (lte *LessThanOrEqual) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
   730  	result, err := lte.Compare(ctx, row)
   731  	if err != nil {
   732  		if ErrNilOperand.Is(err) {
   733  			return nil, nil
   734  		}
   735  
   736  		return nil, err
   737  	}
   738  
   739  	return result < 1, nil
   740  }
   741  
   742  // WithChildren implements the Expression interface.
   743  func (lte *LessThanOrEqual) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   744  	if len(children) != 2 {
   745  		return nil, sql.ErrInvalidChildrenNumber.New(lte, len(children), 2)
   746  	}
   747  	return NewLessThanOrEqual(children[0], children[1]), nil
   748  }
   749  
   750  func (lte *LessThanOrEqual) String() string {
   751  	return fmt.Sprintf("(%s <= %s)", lte.Left(), lte.Right())
   752  }
   753  
   754  func (lte *LessThanOrEqual) DebugString() string {
   755  	pr := sql.NewTreePrinter()
   756  	_ = pr.WriteNode("LessThanOrEqual")
   757  	children := []string{sql.DebugString(lte.Left()), sql.DebugString(lte.Right())}
   758  	_ = pr.WriteChildren(children...)
   759  	return pr.String()
   760  }
   761  
   762  var (
   763  	// ErrUnsupportedInOperand is returned when there is an invalid righthand
   764  	// operand in an IN operator.
   765  	ErrUnsupportedInOperand = errors.NewKind("right operand in IN operation must be tuple, but is %T")
   766  )