micromegas_analytics/dfext/
log_stream_table_provider.rs1use super::task_log_exec_plan::TaskLogExecPlan;
2use async_trait::async_trait;
3use datafusion::arrow::datatypes::SchemaRef;
4use datafusion::catalog::Session;
5use datafusion::catalog::TableProvider;
6use datafusion::datasource::TableType;
7use datafusion::physical_plan::ExecutionPlan;
8use datafusion::physical_plan::limit::GlobalLimitExec;
9use datafusion::physical_plan::projection::ProjectionExec;
10use datafusion::prelude::Expr;
11use std::sync::Arc;
12
13#[derive(Debug)]
15pub struct LogStreamTableProvider {
16 pub log_stream: Arc<TaskLogExecPlan>,
18}
19
20#[async_trait]
21impl TableProvider for LogStreamTableProvider {
22 fn schema(&self) -> SchemaRef {
23 self.log_stream.schema()
24 }
25
26 fn table_type(&self) -> TableType {
27 TableType::Temporary
28 }
29
30 async fn scan(
31 &self,
32 _state: &dyn Session,
33 projection: Option<&Vec<usize>>,
34 _filters: &[Expr],
35 limit: Option<usize>,
36 ) -> datafusion::error::Result<Arc<dyn ExecutionPlan>> {
37 let mut plan: Arc<dyn ExecutionPlan> = self.log_stream.clone();
38 if let Some(projection) = projection {
43 let schema = plan.schema();
44 let projected_exprs: Vec<(Arc<dyn datafusion::physical_expr::PhysicalExpr>, String)> =
45 projection
46 .iter()
47 .map(|&i| {
48 let name = schema.field(i).name().clone();
49 let expr = Arc::new(datafusion::physical_expr::expressions::Column::new(
50 &name, i,
51 ))
52 as Arc<dyn datafusion::physical_expr::PhysicalExpr>;
53 (expr, name)
54 })
55 .collect();
56 plan = Arc::new(ProjectionExec::try_new(projected_exprs, plan)?);
57 }
58 if let Some(fetch) = limit {
61 plan = Arc::new(GlobalLimitExec::new(plan, 0, Some(fetch)));
62 }
63 Ok(plan)
64 }
65}