github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/index/testutils.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 index
    16  
    17  import (
    18  	"github.com/dolthub/go-mysql-server/sql"
    19  
    20  	"github.com/dolthub/dolt/go/libraries/doltcore/table/typed/noms"
    21  	"github.com/dolthub/dolt/go/store/prolly"
    22  	"github.com/dolthub/dolt/go/store/types"
    23  )
    24  
    25  func ClosedRange(tpl1, tpl2 types.Tuple) *noms.ReadRange {
    26  	return CustomRange(tpl1, tpl2, sql.Closed, sql.Closed)
    27  }
    28  
    29  func OpenRange(tpl1, tpl2 types.Tuple) *noms.ReadRange {
    30  	return CustomRange(tpl1, tpl2, sql.Open, sql.Open)
    31  }
    32  
    33  func CustomRange(tpl1, tpl2 types.Tuple, bt1, bt2 sql.RangeBoundType) *noms.ReadRange {
    34  	var nrc nomsRangeCheck
    35  	_ = tpl1.IterFields(func(tupleIndex uint64, tupleVal types.Value) (stop bool, err error) {
    36  		if tupleIndex%2 == 0 {
    37  			return false, nil
    38  		}
    39  		if bt1 == sql.Closed {
    40  			nrc = append(nrc, columnBounds{
    41  				boundsCase: boundsCase_greaterEquals_infinity,
    42  				lowerbound: tupleVal,
    43  			})
    44  		} else {
    45  			nrc = append(nrc, columnBounds{
    46  				boundsCase: boundsCase_greater_infinity,
    47  				lowerbound: tupleVal,
    48  			})
    49  		}
    50  		return false, nil
    51  	})
    52  	_ = tpl2.IterFields(func(tupleIndex uint64, tupleVal types.Value) (stop bool, err error) {
    53  		if tupleIndex%2 == 0 {
    54  			return false, nil
    55  		}
    56  		idx := (tupleIndex - 1) / 2
    57  		if bt2 == sql.Closed {
    58  			// Bounds cases are enum aliases on bytes, and they're arranged such that we can increment the case
    59  			// that was previously set when evaluating the lowerbound to get the proper overall case.
    60  			nrc[idx].boundsCase += 1
    61  			nrc[idx].upperbound = tupleVal
    62  		} else {
    63  			nrc[idx].boundsCase += 2
    64  			nrc[idx].upperbound = tupleVal
    65  		}
    66  		return false, nil
    67  	})
    68  	return &noms.ReadRange{
    69  		Start:     tpl1,
    70  		Inclusive: true,
    71  		Reverse:   false,
    72  		Check:     nrc,
    73  	}
    74  }
    75  
    76  func GreaterThanRange(tpl types.Tuple) *noms.ReadRange {
    77  	var nrc nomsRangeCheck
    78  	_ = tpl.IterFields(func(tupleIndex uint64, tupleVal types.Value) (stop bool, err error) {
    79  		if tupleIndex%2 == 0 {
    80  			return false, nil
    81  		}
    82  		nrc = append(nrc, columnBounds{
    83  			boundsCase: boundsCase_greater_infinity,
    84  			lowerbound: tupleVal,
    85  		})
    86  		return false, nil
    87  	})
    88  	return &noms.ReadRange{
    89  		Start:     tpl,
    90  		Inclusive: true,
    91  		Reverse:   false,
    92  		Check:     nrc,
    93  	}
    94  }
    95  
    96  func LessThanRange(tpl types.Tuple) *noms.ReadRange {
    97  	var nrc nomsRangeCheck
    98  	_ = tpl.IterFields(func(tupleIndex uint64, tupleVal types.Value) (stop bool, err error) {
    99  		if tupleIndex%2 == 0 {
   100  			return false, nil
   101  		}
   102  		nrc = append(nrc, columnBounds{
   103  			boundsCase: boundsCase_infinity_less,
   104  			upperbound: tupleVal,
   105  		})
   106  		return false, nil
   107  	})
   108  	return &noms.ReadRange{
   109  		Start:     types.EmptyTuple(types.Format_Default),
   110  		Inclusive: true,
   111  		Reverse:   false,
   112  		Check:     nrc,
   113  	}
   114  }
   115  
   116  func GreaterOrEqualRange(tpl types.Tuple) *noms.ReadRange {
   117  	var nrc nomsRangeCheck
   118  	_ = tpl.IterFields(func(tupleIndex uint64, tupleVal types.Value) (stop bool, err error) {
   119  		if tupleIndex%2 == 0 {
   120  			return false, nil
   121  		}
   122  		nrc = append(nrc, columnBounds{
   123  			boundsCase: boundsCase_greaterEquals_infinity,
   124  			lowerbound: tupleVal,
   125  		})
   126  		return false, nil
   127  	})
   128  	return &noms.ReadRange{
   129  		Start:     tpl,
   130  		Inclusive: true,
   131  		Reverse:   false,
   132  		Check:     nrc,
   133  	}
   134  }
   135  
   136  func LessOrEqualRange(tpl types.Tuple) *noms.ReadRange {
   137  	var nrc nomsRangeCheck
   138  	_ = tpl.IterFields(func(tupleIndex uint64, tupleVal types.Value) (stop bool, err error) {
   139  		if tupleIndex%2 == 0 {
   140  			return false, nil
   141  		}
   142  		nrc = append(nrc, columnBounds{
   143  			boundsCase: boundsCase_infinity_lessEquals,
   144  			upperbound: tupleVal,
   145  		})
   146  		return false, nil
   147  	})
   148  	return &noms.ReadRange{
   149  		Start:     types.EmptyTuple(types.Format_Default),
   150  		Inclusive: true,
   151  		Reverse:   false,
   152  		Check:     nrc,
   153  	}
   154  }
   155  
   156  func NullRange() *noms.ReadRange {
   157  	return &noms.ReadRange{
   158  		Start:     types.EmptyTuple(types.Format_Default),
   159  		Inclusive: true,
   160  		Reverse:   false,
   161  		Check: nomsRangeCheck{
   162  			{
   163  				boundsCase: boundsCase_isNull,
   164  			},
   165  		},
   166  	}
   167  }
   168  
   169  func NotNullRange() *noms.ReadRange {
   170  	return &noms.ReadRange{
   171  		Start:     types.EmptyTuple(types.Format_Default),
   172  		Inclusive: true,
   173  		Reverse:   false,
   174  		Check: nomsRangeCheck{
   175  			{
   176  				boundsCase: boundsCase_infinity_infinity,
   177  			},
   178  		},
   179  	}
   180  }
   181  
   182  func AllRange() *noms.ReadRange {
   183  	return &noms.ReadRange{
   184  		Start:     types.EmptyTuple(types.Format_Default),
   185  		Inclusive: true,
   186  		Reverse:   false,
   187  		Check:     nomsRangeCheck{},
   188  	}
   189  }
   190  
   191  func ReadRangesEqual(nr1, nr2 *noms.ReadRange) bool {
   192  	if nr1 == nil || nr2 == nil {
   193  		if nr1 == nil && nr2 == nil {
   194  			return true
   195  		}
   196  		return false
   197  	}
   198  	if nr1.Inclusive != nr2.Inclusive || nr1.Reverse != nr2.Reverse || !nr1.Start.Equals(nr2.Start) ||
   199  		!nr1.Check.(nomsRangeCheck).Equals(nr2.Check.(nomsRangeCheck)) {
   200  		return false
   201  	}
   202  	return true
   203  }
   204  
   205  func NomsRangesFromIndexLookup(ctx *sql.Context, lookup sql.IndexLookup) ([]*noms.ReadRange, error) {
   206  	return lookup.Index.(*doltIndex).nomsRanges(ctx, lookup.Ranges...)
   207  }
   208  
   209  func ProllyRangesFromIndexLookup(ctx *sql.Context, lookup sql.IndexLookup) ([]prolly.Range, error) {
   210  	idx := lookup.Index.(*doltIndex)
   211  	return idx.prollyRanges(ctx, idx.ns, lookup.Ranges...)
   212  }
   213  
   214  func DoltIndexFromSqlIndex(idx sql.Index) DoltIndex {
   215  	return idx.(DoltIndex)
   216  }