| 224 | } |
| 225 | |
| 226 | fn try_swapping_with_projection( |
| 227 | &self, |
| 228 | projection: &ProjectionExprs, |
| 229 | ) -> Result<Option<Arc<dyn DataSource>>> { |
| 230 | // If there is any non-column or alias-carrier expression, Projection should not be removed. |
| 231 | // This process can be moved into MemoryExec, but it would be an overlap of their responsibility. |
| 232 | let exprs = projection.iter().cloned().collect_vec(); |
| 233 | all_alias_free_columns(exprs.as_slice()) |
| 234 | .then(|| { |
| 235 | let all_projections = (0..self.schema.fields().len()).collect(); |
| 236 | let new_projections = new_projections_for_columns( |
| 237 | &exprs, |
| 238 | self.projection().as_ref().unwrap_or(&all_projections), |
| 239 | ); |
| 240 | let projected_schema = |
| 241 | project_schema(&self.schema, Some(&new_projections)); |
| 242 | |
| 243 | projected_schema.map(|projected_schema| { |
| 244 | // Clone self to preserve all metadata (fetch, sort_information, |
| 245 | // show_sizes, etc.) then update only the projection-related fields. |
| 246 | let mut new_source = self.clone(); |
| 247 | new_source.projection = Some(new_projections); |
| 248 | new_source.projected_schema = projected_schema; |
| 249 | // Project sort information to match the new projection |
| 250 | new_source.sort_information = project_orderings( |
| 251 | &new_source.sort_information, |
| 252 | &new_source.projected_schema, |
| 253 | ); |
| 254 | Arc::new(new_source) as Arc<dyn DataSource> |
| 255 | }) |
| 256 | }) |
| 257 | .transpose() |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | impl MemorySourceConfig { |