@@ -114,59 +114,58 @@ impl RangeIndex {
114114 where
115115 F : Fn ( & ColumnId ) -> bool ,
116116 {
117- let mut input_domains: HashMap < String , Domain > = self
118- . expr
119- . column_refs ( )
120- . into_iter ( )
121- . map ( |( name, ty) | {
122- // internal column and stream column are not actual stored columns
123- if is_internal_column ( & name) || is_stream_column ( & name) {
124- return Ok ( ( name, Domain :: full ( & ty) ) ) ;
125- }
117+ let mut input_domains = HashMap :: new ( ) ;
118+ let mut virtual_column_types = HashMap :: new ( ) ;
119+ for ( name, ty) in self . expr . column_refs ( ) {
120+ // internal column and stream column are not actual stored columns
121+ if is_internal_column ( & name) || is_stream_column ( & name) {
122+ input_domains. insert ( name, Domain :: full ( & ty) ) ;
123+ continue ;
124+ }
126125
127- let column_ids = self . schema . leaf_columns_of ( & name) ;
128- if column_ids. is_empty ( ) {
129- // The name may refer to a virtual column (e.g. `v['a']`). Use the
130- // block-local virtual column statistics to build the domain.
131- // Only typed statistics are injected; everything else falls back
132- // to a full domain to avoid wrong pruning.
133- let virtual_domain = virtual_col_stats. and_then ( |virtual_col_stats| {
134- virtual_col_stats . get ( & name ) . map ( |stat| {
135- let column_stat = stat. to_column_statistics ( ) ;
136- let data_type = DataType :: from ( & stat . data_type ) ;
137- statistics_to_domain ( vec ! [ & column_stat ] , & data_type)
138- } )
139- } ) ;
140- return Ok ( ( name, virtual_domain . unwrap_or_else ( || Domain :: full ( & ty) ) ) ) ;
126+ let column_ids = self . schema . leaf_columns_of ( & name) ;
127+ if column_ids. is_empty ( ) {
128+ // The name may refer to a virtual column (e.g. `v['a']`). Use the
129+ // block-local virtual column statistics to build the domain.
130+ // Only typed statistics are injected; everything else falls back
131+ // to a full domain to avoid wrong pruning.
132+ if let Some ( stat ) = virtual_col_stats. and_then ( |stats| stats . get ( & name ) ) {
133+ let column_stat = stat . to_column_statistics ( ) ;
134+ let data_type = DataType :: from ( & stat. data_type ) ;
135+ let domain = statistics_to_domain ( vec ! [ & column_stat ] , & data_type) ;
136+ virtual_column_types . insert ( name . clone ( ) , data_type) ;
137+ input_domains . insert ( name , domain ) ;
138+ } else {
139+ input_domains . insert ( name, Domain :: full ( & ty) ) ;
141140 }
141+ continue ;
142+ }
142143
143- let stats = column_ids
144- . iter ( )
145- . filter_map ( |column_id| match stats. get ( column_id) {
146- None => {
147- if column_is_default ( column_id)
148- && self . default_stats . contains_key ( column_id)
149- {
150- Some ( & self . default_stats [ column_id] )
151- } else {
152- None
153- }
144+ let stats = column_ids
145+ . iter ( )
146+ . filter_map ( |column_id| match stats. get ( column_id) {
147+ None => {
148+ if column_is_default ( column_id)
149+ && self . default_stats . contains_key ( column_id)
150+ {
151+ Some ( & self . default_stats [ column_id] )
152+ } else {
153+ None
154154 }
155- other => other,
156- } )
157- . collect ( ) ;
158-
159- let domain = statistics_to_domain ( stats, & ty) ;
160- Ok ( ( name, domain) )
161- } )
162- . collect :: < Result < _ > > ( ) ?;
155+ }
156+ other => other,
157+ } )
158+ . collect ( ) ;
159+ input_domains. insert ( name, statistics_to_domain ( stats, & ty) ) ;
160+ }
163161
164162 for ( name, domain) in self . spatial_predicate_domains ( spatial_stats) {
165163 input_domains. insert ( name, domain) ;
166164 }
167165
168166 let mut visitor = RewriteVisitor {
169167 input_domains,
168+ column_types : ( !virtual_column_types. is_empty ( ) ) . then_some ( & virtual_column_types) ,
170169 func_ctx : & self . func_ctx ,
171170 fn_registry : & BUILTIN_FUNCTIONS ,
172171 } ;
0 commit comments