datafusion/datasource/
empty.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! [`EmptyTable`] useful for testing.
19
20use std::any::Any;
21use std::sync::Arc;
22
23use arrow::datatypes::*;
24use async_trait::async_trait;
25use datafusion_catalog::Session;
26use datafusion_common::project_schema;
27
28use crate::datasource::{TableProvider, TableType};
29use crate::error::Result;
30use crate::logical_expr::Expr;
31use datafusion_physical_plan::empty::EmptyExec;
32use datafusion_physical_plan::ExecutionPlan;
33
34/// An empty plan that is useful for testing and generating plans
35/// without mapping them to actual data.
36#[derive(Debug)]
37pub struct EmptyTable {
38    schema: SchemaRef,
39    partitions: usize,
40}
41
42impl EmptyTable {
43    /// Initialize a new `EmptyTable` from a schema.
44    pub fn new(schema: SchemaRef) -> Self {
45        Self {
46            schema,
47            partitions: 1,
48        }
49    }
50
51    /// Creates a new EmptyTable with specified partition number.
52    pub fn with_partitions(mut self, partitions: usize) -> Self {
53        self.partitions = partitions;
54        self
55    }
56}
57
58#[async_trait]
59impl TableProvider for EmptyTable {
60    fn as_any(&self) -> &dyn Any {
61        self
62    }
63
64    fn schema(&self) -> SchemaRef {
65        Arc::clone(&self.schema)
66    }
67
68    fn table_type(&self) -> TableType {
69        TableType::Base
70    }
71
72    async fn scan(
73        &self,
74        _state: &dyn Session,
75        projection: Option<&Vec<usize>>,
76        _filters: &[Expr],
77        _limit: Option<usize>,
78    ) -> Result<Arc<dyn ExecutionPlan>> {
79        // even though there is no data, projections apply
80        let projected_schema = project_schema(&self.schema, projection)?;
81        Ok(Arc::new(
82            EmptyExec::new(projected_schema).with_partitions(self.partitions),
83        ))
84    }
85}