use std::sync::Arc;
use arrow_schema::SchemaRef;
use datafusion::execution::SendableRecordBatchStream;
use datafusion::logical_expr::Expr;
use datafusion::physical_plan::Statistics;
use smol_str::SmolStr;
use crate::errors::FnError;
use crate::qname::QName;
pub trait CatalogProvider: Send + Sync {
fn name(&self) -> &str;
fn list_labels(&self) -> Result<Vec<CatalogLabel>, FnError>;
fn list_edge_types(&self) -> Result<Vec<CatalogEdgeType>, FnError>;
fn resolve_label(&self, label: &str) -> Option<Arc<dyn CatalogTable>>;
fn resolve_edge_type(&self, edge: &str) -> Option<Arc<dyn CatalogTable>>;
}
#[derive(Clone, Debug)]
pub struct CatalogLabel {
pub name: SmolStr,
pub doc: String,
}
#[derive(Clone, Debug)]
pub struct CatalogEdgeType {
pub name: SmolStr,
pub doc: String,
}
pub trait CatalogTable: Send + Sync {
fn schema(&self) -> SchemaRef;
fn scan(
&self,
projection: Option<&[usize]>,
filters: &[Expr],
limit: Option<usize>,
) -> Result<SendableRecordBatchStream, FnError>;
fn statistics(&self) -> Option<Statistics> {
None
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ReplacementRequest<'a> {
Label(&'a str),
Procedure(&'a QName),
Function(&'a QName),
}
#[non_exhaustive]
pub enum Replacement {
CatalogTable(Arc<dyn CatalogTable>),
Procedure(QName),
Function(QName),
}
impl std::fmt::Debug for Replacement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::CatalogTable(_) => f
.debug_tuple("CatalogTable")
.field(&"<dyn CatalogTable>")
.finish(),
Self::Procedure(q) => f.debug_tuple("Procedure").field(q).finish(),
Self::Function(q) => f.debug_tuple("Function").field(q).finish(),
}
}
}
pub trait ReplacementScanProvider: Send + Sync {
fn replace(&self, request: &ReplacementRequest<'_>) -> Option<Replacement>;
}