@@ -17,45 +17,58 @@ use crate::execution::{ExecArena, ExecId, ExecNode, ExecutionCaches, ExecutorNod
1717use crate :: expression:: range_detacher:: Range ;
1818use crate :: planner:: operator:: table_scan:: TableScanOperator ;
1919use crate :: storage:: { IndexIter , Iter , Transaction } ;
20- use crate :: types:: index:: IndexMetaRef ;
20+ use crate :: types:: index:: { IndexLookup , IndexMetaRef , RuntimeIndexProbe } ;
2121use crate :: types:: serialize:: TupleValueSerializableImpl ;
22+ use std:: array;
23+ use std:: vec;
24+
25+ enum IndexLookupRanges {
26+ One ( array:: IntoIter < Range , 1 > ) ,
27+ Many ( vec:: IntoIter < Range > ) ,
28+ }
29+
30+ impl Iterator for IndexLookupRanges {
31+ type Item = Range ;
32+
33+ fn next ( & mut self ) -> Option < Self :: Item > {
34+ match self {
35+ IndexLookupRanges :: One ( iter) => iter. next ( ) ,
36+ IndexLookupRanges :: Many ( iter) => iter. next ( ) ,
37+ }
38+ }
39+ }
2240
2341pub ( crate ) struct IndexScan < ' a , T : Transaction + ' a > {
2442 op : Option < TableScanOperator > ,
2543 index_by : IndexMetaRef ,
26- ranges : Vec < Range > ,
44+ lookup : Option < IndexLookup > ,
2745 covered_deserializers : Option < Vec < TupleValueSerializableImpl > > ,
2846 cover_mapping : Option < Vec < usize > > ,
29- iter : Option < IndexIter < ' a , T > > ,
47+ iter : Option < IndexIter < ' a , T , IndexLookupRanges > > ,
3048}
3149
3250impl < ' a , T : Transaction + ' a >
3351 From < (
3452 TableScanOperator ,
3553 IndexMetaRef ,
36- Range ,
54+ IndexLookup ,
3755 Option < Vec < TupleValueSerializableImpl > > ,
3856 Option < Vec < usize > > ,
3957 ) > for IndexScan < ' a , T >
4058{
4159 fn from (
42- ( op, index_by, range , covered_deserializers, cover_mapping) : (
60+ ( op, index_by, lookup , covered_deserializers, cover_mapping) : (
4361 TableScanOperator ,
4462 IndexMetaRef ,
45- Range ,
63+ IndexLookup ,
4664 Option < Vec < TupleValueSerializableImpl > > ,
4765 Option < Vec < usize > > ,
4866 ) ,
4967 ) -> Self {
50- let ranges = match range {
51- Range :: SortedRanges ( ranges) => ranges,
52- range => vec ! [ range] ,
53- } ;
54-
5568 IndexScan {
5669 op : Some ( op) ,
5770 index_by,
58- ranges ,
71+ lookup : Some ( lookup ) ,
5972 covered_deserializers,
6073 cover_mapping,
6174 iter : None ,
@@ -78,7 +91,7 @@ impl<'a, T: Transaction + 'a> ExecutorNode<'a, T> for IndexScan<'a, T> {
7891 type Input = (
7992 TableScanOperator ,
8093 IndexMetaRef ,
81- Range ,
94+ IndexLookup ,
8295 Option < Vec < TupleValueSerializableImpl > > ,
8396 Option < Vec < usize > > ,
8497 ) ;
@@ -98,6 +111,27 @@ impl<'a, T: Transaction + 'a> ExecutorNode<'a, T> for IndexScan<'a, T> {
98111}
99112
100113impl < ' a , T : Transaction + ' a > IndexScan < ' a , T > {
114+ fn ranges_from_lookup ( lookup : IndexLookup , arena : & ExecArena < ' a , T > ) -> IndexLookupRanges {
115+ match lookup {
116+ IndexLookup :: Static ( Range :: SortedRanges ( ranges) ) => {
117+ IndexLookupRanges :: Many ( ranges. into_iter ( ) )
118+ }
119+ IndexLookup :: Static ( range) => IndexLookupRanges :: One ( [ range] . into_iter ( ) ) ,
120+ IndexLookup :: Probe ( param) => match arena. runtime_param ( param) {
121+ RuntimeIndexProbe :: Eq ( value) => {
122+ IndexLookupRanges :: One ( [ Range :: Eq ( value. clone ( ) ) ] . into_iter ( ) )
123+ }
124+ RuntimeIndexProbe :: Scope { min, max } => IndexLookupRanges :: One (
125+ [ Range :: Scope {
126+ min : min. clone ( ) ,
127+ max : max. clone ( ) ,
128+ } ]
129+ . into_iter ( ) ,
130+ ) ,
131+ } ,
132+ }
133+ }
134+
101135 pub ( crate ) fn next_tuple ( & mut self , arena : & mut ExecArena < ' a , T > ) -> Result < ( ) , DatabaseError > {
102136 if self . iter . is_none ( ) {
103137 let Some ( TableScanOperator {
@@ -111,13 +145,17 @@ impl<'a, T: Transaction + 'a> IndexScan<'a, T> {
111145 arena. finish ( ) ;
112146 return Ok ( ( ) ) ;
113147 } ;
148+ let ranges = Self :: ranges_from_lookup (
149+ self . lookup . take ( ) . expect ( "index scan lookup initialized" ) ,
150+ arena,
151+ ) ;
114152 self . iter = Some ( arena. transaction ( ) . read_by_index (
115153 arena. table_cache ( ) ,
116154 table_name,
117155 limit,
118156 columns,
119157 self . index_by . clone ( ) ,
120- std :: mem :: take ( & mut self . ranges ) ,
158+ ranges,
121159 with_pk,
122160 self . covered_deserializers . take ( ) ,
123161 self . cover_mapping . take ( ) ,
0 commit comments