datafusion_orc/
file_source.rs1use crate::physical_exec::OrcOpener;
19use datafusion::common::tree_node::TreeNodeRecursion;
20use datafusion::common::DataFusionError;
21use datafusion::datasource::physical_plan::{FileOpener, FileScanConfig, FileSource};
22use datafusion::datasource::table_schema::TableSchema;
23use datafusion::object_store::ObjectStore;
24use datafusion::physical_plan::metrics::ExecutionPlanMetricsSet;
25use datafusion::physical_plan::projection::ProjectionExprs;
26use datafusion::physical_plan::PhysicalExpr;
27use std::sync::Arc;
28
29#[derive(Debug, Clone)]
30pub struct OrcSource {
31 metrics: ExecutionPlanMetricsSet,
32 batch_size: usize,
33 table_schema: TableSchema,
34 projection: ProjectionExprs,
35}
36
37impl OrcSource {
38 pub fn new(table_schema: TableSchema) -> Self {
39 let table_schema_ref = table_schema.table_schema();
40 let projection = ProjectionExprs::from_indices(
41 &(0..table_schema_ref.fields().len()).collect::<Vec<_>>(),
42 table_schema_ref,
43 );
44 Self {
45 metrics: ExecutionPlanMetricsSet::default(),
46 batch_size: 1024,
47 table_schema,
48 projection,
49 }
50 }
51}
52
53impl FileSource for OrcSource {
54 fn create_file_opener(
55 &self,
56 object_store: Arc<dyn ObjectStore>,
57 config: &FileScanConfig,
58 _partition: usize,
59 ) -> Result<Arc<dyn FileOpener>, DataFusionError> {
60 OrcOpener::try_new(
61 object_store,
62 self.table_schema.table_schema().clone(),
63 config.batch_size.unwrap_or(self.batch_size),
64 self.projection.clone(),
65 )
66 .map(|f| Arc::new(f) as Arc<dyn FileOpener>)
67 }
68
69 fn table_schema(&self) -> &TableSchema {
70 &self.table_schema
71 }
72
73 fn with_batch_size(&self, batch_size: usize) -> Arc<dyn FileSource> {
74 Arc::new(Self {
75 batch_size,
76 ..self.clone()
77 })
78 }
79
80 fn projection(&self) -> Option<&ProjectionExprs> {
81 Some(&self.projection)
82 }
83
84 fn metrics(&self) -> &ExecutionPlanMetricsSet {
85 &self.metrics
86 }
87
88 fn file_type(&self) -> &str {
89 "orc"
90 }
91
92 fn try_pushdown_projection(
93 &self,
94 projection: &ProjectionExprs,
95 ) -> Result<Option<Arc<dyn FileSource>>, DataFusionError> {
96 let mut source = self.clone();
97 source.projection = self.projection.try_merge(projection)?;
98 Ok(Some(Arc::new(source)))
99 }
100
101 fn apply_expressions(
102 &self,
103 f: &mut dyn FnMut(&Arc<dyn PhysicalExpr>) -> Result<TreeNodeRecursion, DataFusionError>,
104 ) -> Result<TreeNodeRecursion, DataFusionError> {
105 datafusion::physical_plan::apply_expression_roots(self.projection.iter(), f)
106 }
107}