use std::any::Any;
use std::borrow::Cow;
use std::fmt::Debug;
use std::sync::Arc;
use crate::session::Session;
use arrow::datatypes::SchemaRef;
use async_trait::async_trait;
use datafusion_common::Result;
use datafusion_common::{not_impl_err, Constraints, Statistics};
use datafusion_expr::Expr;
use datafusion_expr::dml::InsertOp;
use datafusion_expr::{
CreateExternalTable, LogicalPlan, TableProviderFilterPushDown, TableType,
};
use datafusion_physical_plan::ExecutionPlan;
#[async_trait]
pub trait TableProvider: Debug + Sync + Send {
fn as_any(&self) -> &dyn Any;
fn schema(&self) -> SchemaRef;
fn constraints(&self) -> Option<&Constraints> {
None
}
fn table_type(&self) -> TableType;
fn get_table_definition(&self) -> Option<&str> {
None
}
fn get_logical_plan(&self) -> Option<Cow<LogicalPlan>> {
None
}
fn get_column_default(&self, _column: &str) -> Option<&Expr> {
None
}
async fn scan(
&self,
state: &dyn Session,
projection: Option<&Vec<usize>>,
filters: &[Expr],
limit: Option<usize>,
) -> Result<Arc<dyn ExecutionPlan>>;
fn supports_filters_pushdown(
&self,
filters: &[&Expr],
) -> Result<Vec<TableProviderFilterPushDown>> {
Ok(vec![
TableProviderFilterPushDown::Unsupported;
filters.len()
])
}
fn statistics(&self) -> Option<Statistics> {
None
}
async fn insert_into(
&self,
_state: &dyn Session,
_input: Arc<dyn ExecutionPlan>,
_insert_op: InsertOp,
) -> Result<Arc<dyn ExecutionPlan>> {
not_impl_err!("Insert into not implemented for this table")
}
}
#[async_trait]
pub trait TableProviderFactory: Debug + Sync + Send {
async fn create(
&self,
state: &dyn Session,
cmd: &CreateExternalTable,
) -> Result<Arc<dyn TableProvider>>;
}
pub trait TableFunctionImpl: Debug + Sync + Send {
fn call(&self, args: &[Expr]) -> Result<Arc<dyn TableProvider>>;
}
#[derive(Debug)]
pub struct TableFunction {
name: String,
fun: Arc<dyn TableFunctionImpl>,
}
impl TableFunction {
pub fn new(name: String, fun: Arc<dyn TableFunctionImpl>) -> Self {
Self { name, fun }
}
pub fn name(&self) -> &str {
&self.name
}
pub fn function(&self) -> &Arc<dyn TableFunctionImpl> {
&self.fun
}
pub fn create_table_provider(&self, args: &[Expr]) -> Result<Arc<dyn TableProvider>> {
self.fun.call(args)
}
}