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 }