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

     1  // Copyright 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 sql
    16  
    17  import (
    18  	"fmt"
    19  	"sort"
    20  	"strings"
    21  )
    22  
    23  // RangeType returns what a RangeColumnExpr represents, such as a GreaterThan on some column, or a column set between
    24  // two bounds.
    25  type RangeType int
    26  
    27  const (
    28  	RangeType_Invalid           RangeType = iota // This range is invalid, which should not be possible. Please create a GitHub issue if this is ever returned.
    29  	RangeType_Empty                              // This range represents the empty set of values.
    30  	RangeType_All                                // This range represents every possible value.
    31  	RangeType_GreaterThan                        // This range is equivalent to checking for all values greater than the lowerbound.
    32  	RangeType_GreaterOrEqual                     // This range is equivalent to checking for all values greater than or equal to the lowerbound.
    33  	RangeType_LessThanOrNull                     // This range is equivalent to checking for all values less than the upperbound.
    34  	RangeType_LessOrEqualOrNull                  // This range is equivalent to checking for all values less than or equal to the upperbound.
    35  	RangeType_ClosedClosed                       // This range covers a finite set of values with the lower and upperbounds inclusive.
    36  	RangeType_OpenOpen                           // This range covers a finite set of values with the lower and upperbounds exclusive.
    37  	RangeType_OpenClosed                         // This range covers a finite set of values with the lowerbound exclusive and upperbound inclusive.
    38  	RangeType_ClosedOpen                         // This range covers a finite set of values with the lowerbound inclusive and upperbound exclusive.
    39  	RangeType_EqualNull                          // A range matching only NULL.
    40  )
    41  
    42  // RangeColumnExpr represents the contiguous set of values on a specific column.
    43  type RangeColumnExpr struct {
    44  	LowerBound RangeCut
    45  	UpperBound RangeCut
    46  	Typ        Type
    47  }
    48  
    49  // OpenRangeColumnExpr returns a RangeColumnExpr representing {l < x < u}.
    50  func OpenRangeColumnExpr(lower, upper interface{}, typ Type) RangeColumnExpr {
    51  	if lower == nil || upper == nil {
    52  		return EmptyRangeColumnExpr(typ)
    53  	}
    54  	return RangeColumnExpr{
    55  		Above{Key: lower},
    56  		Below{Key: upper},
    57  		typ,
    58  	}
    59  }
    60  
    61  // ClosedRangeColumnExpr returns a RangeColumnExpr representing {l <= x <= u}.
    62  func ClosedRangeColumnExpr(lower, upper interface{}, typ Type) RangeColumnExpr {
    63  	if lower == nil || upper == nil {
    64  		return EmptyRangeColumnExpr(typ)
    65  	}
    66  	return RangeColumnExpr{
    67  		Below{Key: lower},
    68  		Above{Key: upper},
    69  		typ,
    70  	}
    71  }
    72  
    73  // CustomRangeColumnExpr returns a RangeColumnExpr defined by the bounds given.
    74  func CustomRangeColumnExpr(lower, upper interface{}, lowerBound, upperBound RangeBoundType, typ Type) RangeColumnExpr {
    75  	if lower == nil || upper == nil {
    76  		return EmptyRangeColumnExpr(typ)
    77  	}
    78  	var lCut RangeCut
    79  	var uCut RangeCut
    80  	if lowerBound == Open {
    81  		lCut = Above{Key: lower}
    82  	} else {
    83  		lCut = Below{Key: lower}
    84  	}
    85  	if upperBound == Open {
    86  		uCut = Below{Key: upper}
    87  	} else {
    88  		uCut = Above{Key: upper}
    89  	}
    90  	return RangeColumnExpr{
    91  		lCut,
    92  		uCut,
    93  		typ,
    94  	}
    95  }
    96  
    97  // LessThanRangeColumnExpr returns a RangeColumnExpr representing {x < u}.
    98  func LessThanRangeColumnExpr(upper interface{}, typ Type) RangeColumnExpr {
    99  	if upper == nil {
   100  		return EmptyRangeColumnExpr(typ)
   101  	}
   102  	return RangeColumnExpr{
   103  		AboveNull{},
   104  		Below{Key: upper},
   105  		typ,
   106  	}
   107  }
   108  
   109  // LessOrEqualRangeColumnExpr returns a RangeColumnExpr representing  {x <= u}.
   110  func LessOrEqualRangeColumnExpr(upper interface{}, typ Type) RangeColumnExpr {
   111  	if upper == nil {
   112  		return EmptyRangeColumnExpr(typ)
   113  	}
   114  	return RangeColumnExpr{
   115  		AboveNull{},
   116  		Above{Key: upper},
   117  		typ,
   118  	}
   119  }
   120  
   121  // GreaterThanRangeColumnExpr returns a RangeColumnExpr representing {x > l}.
   122  func GreaterThanRangeColumnExpr(lower interface{}, typ Type) RangeColumnExpr {
   123  	if lower == nil {
   124  		return EmptyRangeColumnExpr(typ)
   125  	}
   126  	return RangeColumnExpr{
   127  		Above{Key: lower},
   128  		AboveAll{},
   129  		typ,
   130  	}
   131  }
   132  
   133  // GreaterOrEqualRangeColumnExpr returns a RangeColumnExpr representing {x >= l}.
   134  func GreaterOrEqualRangeColumnExpr(lower interface{}, typ Type) RangeColumnExpr {
   135  	if lower == nil {
   136  		return EmptyRangeColumnExpr(typ)
   137  	}
   138  	return RangeColumnExpr{
   139  		Below{Key: lower},
   140  		AboveAll{},
   141  		typ,
   142  	}
   143  }
   144  
   145  // AllRangeColumnExpr returns a RangeColumnExpr representing all values.
   146  func AllRangeColumnExpr(typ Type) RangeColumnExpr {
   147  	return RangeColumnExpr{
   148  		BelowNull{},
   149  		AboveAll{},
   150  		typ,
   151  	}
   152  }
   153  
   154  // EmptyRangeColumnExpr returns the empty RangeColumnExpr for the given type.
   155  func EmptyRangeColumnExpr(typ Type) RangeColumnExpr {
   156  	return RangeColumnExpr{
   157  		AboveAll{},
   158  		AboveAll{},
   159  		typ,
   160  	}
   161  }
   162  
   163  // NullRangeColumnExpr returns the null RangeColumnExpr for the given type.
   164  func NullRangeColumnExpr(typ Type) RangeColumnExpr {
   165  	return RangeColumnExpr{
   166  		LowerBound: BelowNull{},
   167  		UpperBound: AboveNull{},
   168  		Typ:        typ,
   169  	}
   170  }
   171  
   172  // NotNullRangeColumnExpr returns the not null RangeColumnExpr for the given type.
   173  func NotNullRangeColumnExpr(typ Type) RangeColumnExpr {
   174  	return RangeColumnExpr{
   175  		AboveNull{},
   176  		AboveAll{},
   177  		typ,
   178  	}
   179  }
   180  
   181  // Equals checks for equality with the given RangeColumnExpr.
   182  func (r RangeColumnExpr) Equals(other RangeColumnExpr) (bool, error) {
   183  	cmpLower, err := r.LowerBound.Compare(other.LowerBound, r.Typ)
   184  	if err != nil {
   185  		return false, err
   186  	}
   187  	cmpUpper, err := r.UpperBound.Compare(other.UpperBound, r.Typ)
   188  	if err != nil {
   189  		return false, err
   190  	}
   191  	return cmpLower == 0 && cmpUpper == 0, nil
   192  }
   193  
   194  // HasLowerBound returns whether this RangeColumnExpr has a value for the lower bound.
   195  func (r RangeColumnExpr) HasLowerBound() bool {
   196  	return RangeCutIsBinding(r.LowerBound)
   197  }
   198  
   199  // HasUpperBound returns whether this RangeColumnExpr has a value for the upper bound.
   200  func (r RangeColumnExpr) HasUpperBound() bool {
   201  	return RangeCutIsBinding(r.UpperBound)
   202  }
   203  
   204  // IsEmpty returns whether this RangeColumnExpr is empty.
   205  func (r RangeColumnExpr) IsEmpty() (bool, error) {
   206  	cmp, err := r.LowerBound.Compare(r.UpperBound, r.Typ)
   207  	return cmp >= 0, err
   208  }
   209  
   210  // IsConnected evaluates whether the given RangeColumnExpr overlaps or is adjacent to the calling RangeColumnExpr.
   211  func (r RangeColumnExpr) IsConnected(other RangeColumnExpr) (bool, error) {
   212  	if r.Typ.String() != other.Typ.String() {
   213  		return false, nil
   214  	}
   215  	comp, err := r.LowerBound.Compare(other.UpperBound, r.Typ)
   216  	if err != nil {
   217  		return false, err
   218  	}
   219  	if comp > 0 {
   220  		return false, nil
   221  	}
   222  	comp, err = other.LowerBound.Compare(r.UpperBound, r.Typ)
   223  	if err != nil {
   224  		return false, err
   225  	}
   226  	return comp <= 0, nil
   227  }
   228  
   229  // Overlaps evaluates whether the given RangeColumnExpr overlaps the calling RangeColumnExpr. If they do, returns the
   230  // overlapping region as a RangeColumnExpr.
   231  func (r RangeColumnExpr) Overlaps(other RangeColumnExpr) (RangeColumnExpr, bool, error) {
   232  	if r.Typ.String() != other.Typ.String() {
   233  		return EmptyRangeColumnExpr(r.Typ), false, nil
   234  	}
   235  	comp, err := r.LowerBound.Compare(other.UpperBound, r.Typ)
   236  	if err != nil || comp >= 0 {
   237  		return EmptyRangeColumnExpr(r.Typ), false, err
   238  	}
   239  	comp, err = other.LowerBound.Compare(r.UpperBound, r.Typ)
   240  	if err != nil || comp >= 0 {
   241  		return EmptyRangeColumnExpr(r.Typ), false, err
   242  	}
   243  	lowerbound, err := GetRangeCutMax(r.Typ, r.LowerBound, other.LowerBound)
   244  	if err != nil {
   245  		return EmptyRangeColumnExpr(r.Typ), false, err
   246  	}
   247  	upperbound, err := GetRangeCutMin(r.Typ, r.UpperBound, other.UpperBound)
   248  	if err != nil {
   249  		return EmptyRangeColumnExpr(r.Typ), false, err
   250  	}
   251  	return RangeColumnExpr{
   252  		LowerBound: lowerbound,
   253  		UpperBound: upperbound,
   254  		Typ:        r.Typ,
   255  	}, true, nil
   256  }
   257  
   258  // Subtract removes the given RangeColumnExpr from the calling RangeColumnExpr. In the event that the given
   259  // RangeColumnExpr is a strict subset of the calling RangeColumnExpr, two RangeColumnExprs will be returned. If the
   260  // given RangeColumnExpr does not overlap the calling RangeColumnExpr, then the calling RangeColumnExpr is returned.
   261  // If the calling RangeColumnExpr is a strict subset (or equivalent) of the given RangeColumnExpr, then an empty slice
   262  // is returned. In all other cases, a slice with a single RangeColumnExpr will be returned.
   263  func (r RangeColumnExpr) Subtract(other RangeColumnExpr) ([]RangeColumnExpr, error) {
   264  	_, overlaps, err := r.Overlaps(other)
   265  	if err != nil {
   266  		return nil, err
   267  	}
   268  	if !overlaps {
   269  		return []RangeColumnExpr{r}, nil
   270  	}
   271  	lComp, err := r.LowerBound.Compare(other.LowerBound, r.Typ)
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  	uComp, err := r.UpperBound.Compare(other.UpperBound, r.Typ)
   276  	if err != nil {
   277  		return nil, err
   278  	}
   279  	// Each bound, when compared to the other, has 3 possible states: less (-1), equal (0), or greater (1).
   280  	// As there are two bounds (upper and lower), that gives us 9 total combinations.
   281  	// To make use of a switch statement (avoiding 9 if-else statements), we can convert the states to an integer.
   282  	// Adding 1 to each bound moves the lowest value to 0 and highest to 2, so we can use it as a trit (ternary "bit").
   283  	switch (3 * (lComp + 1)) + (uComp + 1) {
   284  	case 0: // lComp == -1 && uComp == -1
   285  		return []RangeColumnExpr{{r.LowerBound, other.LowerBound, r.Typ}}, nil
   286  	case 1: // lComp == -1 && uComp == 0
   287  		return []RangeColumnExpr{{r.LowerBound, other.LowerBound, r.Typ}}, nil
   288  	case 2: // lComp == -1 && uComp == 1
   289  		return []RangeColumnExpr{
   290  			{r.LowerBound, other.LowerBound, r.Typ},
   291  			{other.UpperBound, r.UpperBound, r.Typ},
   292  		}, nil
   293  	case 3: // lComp == 0  && uComp == -1
   294  		return nil, nil
   295  	case 4: // lComp == 0  && uComp == 0
   296  		return nil, nil
   297  	case 5: // lComp == 0  && uComp == 1
   298  		return []RangeColumnExpr{{other.UpperBound, r.UpperBound, r.Typ}}, nil
   299  	case 6: // lComp == 1  && uComp == -1
   300  		return nil, nil
   301  	case 7: // lComp == 1  && uComp == 0
   302  		return nil, nil
   303  	case 8: // lComp == 1  && uComp == 1
   304  		return []RangeColumnExpr{{other.UpperBound, r.UpperBound, r.Typ}}, nil
   305  	default: // should never be hit
   306  		panic(fmt.Errorf("unknown RangeColumnExpr subtraction case: %d", (3*(lComp+1))+(uComp+1)))
   307  	}
   308  }
   309  
   310  // IsSubsetOf evaluates whether the calling RangeColumnExpr is fully encompassed by the given RangeColumnExpr.
   311  func (r RangeColumnExpr) IsSubsetOf(other RangeColumnExpr) (bool, error) {
   312  	if r.Typ.String() != other.Typ.String() {
   313  		return false, nil
   314  	}
   315  	comp, err := r.LowerBound.Compare(other.LowerBound, r.Typ)
   316  	if err != nil || comp == -1 {
   317  		return false, err
   318  	}
   319  	comp, err = r.UpperBound.Compare(other.UpperBound, r.Typ)
   320  	if err != nil || comp == 1 {
   321  		return false, err
   322  	}
   323  	return true, nil
   324  }
   325  
   326  // IsSupersetOf evaluates whether the calling RangeColumnExpr fully encompasses the given RangeColumnExpr.
   327  func (r RangeColumnExpr) IsSupersetOf(other RangeColumnExpr) (bool, error) {
   328  	return other.IsSubsetOf(r)
   329  }
   330  
   331  // String returns this RangeColumnExpr as a string for display purposes.
   332  func (r RangeColumnExpr) String() string {
   333  	return fmt.Sprintf("(%s, %s)", r.LowerBound.String(), r.UpperBound.String())
   334  }
   335  
   336  // DebugString returns this RangeColumnExpr as a string for debugging purposes.
   337  func (r RangeColumnExpr) DebugString() string {
   338  	var lowerB interface{} = "-∞"
   339  	if RangeCutIsBinding(r.LowerBound) {
   340  		lowerB = GetRangeCutKey(r.LowerBound)
   341  	}
   342  	var upperB interface{} = "∞"
   343  	if RangeCutIsBinding(r.UpperBound) {
   344  		upperB = GetRangeCutKey(r.UpperBound)
   345  	}
   346  	switch v := lowerB.(type) {
   347  	case []byte:
   348  		lowerB = string(v)
   349  	}
   350  	switch v := upperB.(type) {
   351  	case []byte:
   352  		upperB = string(v)
   353  	}
   354  
   355  	sb := strings.Builder{}
   356  	switch r.LowerBound.(type) {
   357  	case Above:
   358  		lowerB := GetRangeCutKey(r.LowerBound)
   359  		sb.WriteString("(" + fmt.Sprint(lowerB))
   360  	case Below:
   361  		lowerB := GetRangeCutKey(r.LowerBound)
   362  		sb.WriteString("[" + fmt.Sprint(lowerB))
   363  	case AboveAll:
   364  		sb.WriteString("(∞")
   365  	case AboveNull:
   366  		sb.WriteString("(NULL")
   367  	case BelowNull:
   368  		sb.WriteString("[NULL")
   369  	}
   370  	sb.WriteString(", ")
   371  	switch r.UpperBound.(type) {
   372  	case Above:
   373  		upperB := GetRangeCutKey(r.UpperBound)
   374  		sb.WriteString(fmt.Sprint(upperB) + "]")
   375  	case Below:
   376  		upperB := GetRangeCutKey(r.UpperBound)
   377  		sb.WriteString(fmt.Sprint(upperB) + ")")
   378  	case AboveAll:
   379  		sb.WriteString("∞)")
   380  	case AboveNull:
   381  		sb.WriteString("NULL]")
   382  	case BelowNull:
   383  		sb.WriteString("NULL)")
   384  	}
   385  	return sb.String()
   386  }
   387  
   388  // TryIntersect attempts to intersect the given RangeColumnExpr with the calling RangeColumnExpr. Returns true if the
   389  // intersection result is not the empty RangeColumnExpr, however a valid RangeColumnExpr is always returned if the error
   390  // is nil.
   391  func (r RangeColumnExpr) TryIntersect(other RangeColumnExpr) (RangeColumnExpr, bool, error) {
   392  	_, l, err := OrderedCuts(r.LowerBound, other.LowerBound, r.Typ)
   393  	if err != nil {
   394  		return RangeColumnExpr{}, false, err
   395  	}
   396  	u, _, err := OrderedCuts(r.UpperBound, other.UpperBound, r.Typ)
   397  	if err != nil {
   398  		return RangeColumnExpr{}, false, err
   399  	}
   400  	comp, err := l.Compare(u, r.Typ)
   401  	if err != nil {
   402  		return RangeColumnExpr{}, false, err
   403  	}
   404  	if comp < 0 {
   405  		return RangeColumnExpr{l, u, r.Typ}, true, nil
   406  	}
   407  	return EmptyRangeColumnExpr(r.Typ), false, nil
   408  }
   409  
   410  // TryUnion attempts to combine the given RangeColumnExpr with the calling RangeColumnExpr. Returns true if the union
   411  // was a success.
   412  func (r RangeColumnExpr) TryUnion(other RangeColumnExpr) (RangeColumnExpr, bool, error) {
   413  	if isEmpty, err := other.IsEmpty(); err != nil {
   414  		return RangeColumnExpr{}, false, err
   415  	} else if isEmpty {
   416  		return r, true, nil
   417  	}
   418  	if isEmpty, err := r.IsEmpty(); err != nil {
   419  		return RangeColumnExpr{}, false, err
   420  	} else if isEmpty {
   421  		return other, true, nil
   422  	}
   423  	connected, err := r.IsConnected(other)
   424  	if err != nil {
   425  		return RangeColumnExpr{}, false, err
   426  	}
   427  	if !connected {
   428  		return RangeColumnExpr{}, false, nil
   429  	}
   430  	l, _, err := OrderedCuts(r.LowerBound, other.LowerBound, r.Typ)
   431  	if err != nil {
   432  		return RangeColumnExpr{}, false, err
   433  	}
   434  	_, u, err := OrderedCuts(r.UpperBound, other.UpperBound, r.Typ)
   435  	if err != nil {
   436  		return RangeColumnExpr{}, false, err
   437  	}
   438  	return RangeColumnExpr{l, u, r.Typ}, true, nil
   439  }
   440  
   441  // Type returns this RangeColumnExpr's RangeType.
   442  func (r RangeColumnExpr) Type() RangeType {
   443  	switch r.LowerBound.(type) {
   444  	case Above:
   445  		switch r.UpperBound.(type) {
   446  		case Above:
   447  			return RangeType_OpenClosed
   448  		case AboveAll:
   449  			return RangeType_GreaterThan
   450  		case Below:
   451  			return RangeType_OpenOpen
   452  		}
   453  	case AboveAll:
   454  		switch r.UpperBound.(type) {
   455  		case AboveAll:
   456  			return RangeType_Empty
   457  		}
   458  	case Below:
   459  		switch r.UpperBound.(type) {
   460  		case Above:
   461  			return RangeType_ClosedClosed
   462  		case AboveAll:
   463  			return RangeType_GreaterOrEqual
   464  		case Below:
   465  			return RangeType_ClosedOpen
   466  		}
   467  	case AboveNull:
   468  		switch r.UpperBound.(type) {
   469  		case Above:
   470  			return RangeType_OpenClosed
   471  		case AboveAll:
   472  			// TODO: NotNull?
   473  			return RangeType_GreaterThan
   474  		case Below:
   475  			return RangeType_OpenOpen
   476  		case AboveNull:
   477  			return RangeType_Empty
   478  		}
   479  	case BelowNull:
   480  		switch r.UpperBound.(type) {
   481  		case Above:
   482  			return RangeType_LessOrEqualOrNull
   483  		case AboveAll:
   484  			return RangeType_All
   485  		case Below:
   486  			return RangeType_LessThanOrNull
   487  		case AboveNull:
   488  			return RangeType_EqualNull
   489  		case BelowNull:
   490  			return RangeType_Empty
   491  		}
   492  	}
   493  	return RangeType_Invalid
   494  }
   495  
   496  // RepresentsEquals returns whether this RangeColumnExpr represents an "equals". An "equals" is a special kind of
   497  // RangeType_ClosedClosed that iterates over a single value (or the specific prefix of some value).
   498  func (r RangeColumnExpr) RepresentsEquals() (bool, error) {
   499  	if r.Type() == RangeType_ClosedClosed {
   500  		cmp, err := r.Typ.Compare(GetRangeCutKey(r.LowerBound), GetRangeCutKey(r.UpperBound))
   501  		if err != nil {
   502  			return false, err
   503  		}
   504  		return cmp == 0, nil
   505  	}
   506  	return false, nil
   507  }
   508  
   509  // OrderedCuts returns the given Cuts in order from lowest-touched values to highest-touched values.
   510  func OrderedCuts(l, r RangeCut, typ Type) (RangeCut, RangeCut, error) {
   511  	comp, err := l.Compare(r, typ)
   512  	if err != nil {
   513  		return nil, nil, err
   514  	}
   515  	if comp <= 0 {
   516  		return l, r, nil
   517  	}
   518  	return r, l, nil
   519  }
   520  
   521  // rangeColumnExprSlice is a sortable slice of RangeColumnExprs.
   522  type rangeColumnExprSlice struct {
   523  	ranges []RangeColumnExpr
   524  	err    error
   525  }
   526  
   527  func (r *rangeColumnExprSlice) Len() int      { return len(r.ranges) }
   528  func (r *rangeColumnExprSlice) Swap(i, j int) { r.ranges[i], r.ranges[j] = r.ranges[j], r.ranges[i] }
   529  func (r *rangeColumnExprSlice) Less(i, j int) bool {
   530  	lc, err := r.ranges[i].LowerBound.Compare(r.ranges[j].LowerBound, r.ranges[i].Typ)
   531  	if err != nil {
   532  		r.err = err
   533  		return false
   534  	}
   535  	if lc < 0 {
   536  		return true
   537  	} else if lc > 0 {
   538  		return false
   539  	}
   540  	uc, err := r.ranges[i].UpperBound.Compare(r.ranges[j].UpperBound, r.ranges[i].Typ)
   541  	if err != nil {
   542  		r.err = err
   543  		return false
   544  	}
   545  	return uc < 0
   546  }
   547  
   548  // SimplifyRangeColumn combines all RangeColumnExprs that are connected and returns a new slice.
   549  func SimplifyRangeColumn(rces ...RangeColumnExpr) ([]RangeColumnExpr, error) {
   550  	if len(rces) == 0 {
   551  		return rces, nil
   552  	}
   553  	typ := rces[0].Typ
   554  	for i := 1; i < len(rces); i++ {
   555  		if typ.Type() != rces[i].Typ.Type() {
   556  			return nil, fmt.Errorf("may only simplify ranges that share the same type")
   557  		}
   558  	}
   559  	sorted := make([]RangeColumnExpr, len(rces))
   560  	copy(sorted, rces)
   561  	rSlice := &rangeColumnExprSlice{ranges: sorted}
   562  	sort.Sort(rSlice)
   563  	if rSlice.err != nil {
   564  		return nil, rSlice.err
   565  	}
   566  	var res []RangeColumnExpr
   567  	cur := EmptyRangeColumnExpr(rces[0].Typ)
   568  	for _, r := range sorted {
   569  		merged, ok, err := cur.TryUnion(r)
   570  		if err != nil {
   571  			return nil, err
   572  		}
   573  		if ok {
   574  			cur = merged
   575  		} else if curIsEmpty, err := cur.IsEmpty(); err != nil {
   576  			return nil, err
   577  		} else if !curIsEmpty {
   578  			res = append(res, cur)
   579  			cur = r
   580  		}
   581  	}
   582  	if curIsEmpty, err := cur.IsEmpty(); err != nil {
   583  		return nil, err
   584  	} else if !curIsEmpty {
   585  		res = append(res, cur)
   586  	}
   587  	return res, nil
   588  }