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}