use std::fmt::{self, Formatter};
use std::sync::Arc;
use datafusion::common::config::ConfigOptions;
use datafusion::datasource::physical_plan::{FileOpener, FileScanConfig, FileSource};
use datafusion::datasource::table_schema::TableSchema;
use datafusion::error::Result as DataFusionResult;
use datafusion::physical_expr::projection::ProjectionExprs;
use datafusion::physical_expr::{EquivalenceProperties, LexOrdering, PhysicalExpr};
use datafusion::physical_expr_common::sort_expr::PhysicalSortExpr;
use datafusion::physical_plan::filter_pushdown::{FilterPushdownPropagation, PushedDown};
use datafusion::physical_plan::metrics::ExecutionPlanMetricsSet;
use datafusion::physical_plan::{DisplayFormatType, SortOrderPushdownResult};
use datafusion_datasource::morsel::Morselizer;
use object_store::ObjectStore;
pub(crate) struct PositionalFileSource {
inner: Arc<dyn FileSource>,
}
impl PositionalFileSource {
pub(crate) fn wrap(inner: Arc<dyn FileSource>) -> Arc<dyn FileSource> {
Arc::new(Self {
inner,
})
}
fn rewrap(&self, src: Arc<dyn FileSource>) -> Arc<dyn FileSource> {
Arc::new(Self {
inner: src,
})
}
}
impl FileSource for PositionalFileSource {
fn create_file_opener(
&self,
object_store: Arc<dyn ObjectStore>,
base_config: &FileScanConfig,
partition: usize,
) -> DataFusionResult<Arc<dyn FileOpener>> {
self.inner
.create_file_opener(object_store, base_config, partition)
}
fn create_morselizer(
&self,
object_store: Arc<dyn ObjectStore>,
base_config: &FileScanConfig,
partition: usize,
) -> DataFusionResult<Box<dyn Morselizer>> {
self.inner
.create_morselizer(object_store, base_config, partition)
}
fn table_schema(&self) -> &TableSchema {
self.inner.table_schema()
}
fn filter(&self) -> Option<Arc<dyn PhysicalExpr>> {
self.inner.filter()
}
fn projection(&self) -> Option<&ProjectionExprs> {
self.inner.projection()
}
fn metrics(&self) -> &ExecutionPlanMetricsSet {
self.inner.metrics()
}
fn file_type(&self) -> &str {
self.inner.file_type()
}
fn fmt_extra(&self, t: DisplayFormatType, f: &mut Formatter) -> fmt::Result {
self.inner.fmt_extra(t, f)
}
fn with_batch_size(&self, batch_size: usize) -> Arc<dyn FileSource> {
self.rewrap(self.inner.with_batch_size(batch_size))
}
fn try_pushdown_projection(
&self,
projection: &ProjectionExprs,
) -> DataFusionResult<Option<Arc<dyn FileSource>>> {
Ok(self
.inner
.try_pushdown_projection(projection)?
.map(|s| self.rewrap(s)))
}
fn supports_repartitioning(&self) -> bool {
false
}
fn repartitioned(
&self,
_target_partitions: usize,
_repartition_file_min_size: usize,
_output_ordering: Option<LexOrdering>,
_config: &FileScanConfig,
) -> DataFusionResult<Option<FileScanConfig>> {
Ok(None)
}
fn try_pushdown_filters(
&self,
filters: Vec<Arc<dyn PhysicalExpr>>,
_config: &ConfigOptions,
) -> DataFusionResult<FilterPushdownPropagation<Arc<dyn FileSource>>> {
Ok(FilterPushdownPropagation::with_parent_pushdown_result(
vec![PushedDown::No; filters.len()],
))
}
fn try_pushdown_sort(
&self,
_order: &[PhysicalSortExpr],
_eq_properties: &EquivalenceProperties,
) -> DataFusionResult<SortOrderPushdownResult<Arc<dyn FileSource>>> {
Ok(SortOrderPushdownResult::Unsupported)
}
}