datafusion_remote_table/
unparse.rs

1use crate::{DFResult, RemoteDbType};
2use datafusion::common::tree_node::{TreeNode, TreeNodeRecursion};
3use datafusion::logical_expr::{Expr, TableProviderFilterPushDown};
4use std::fmt::Debug;
5
6pub trait Unparse: Debug + Send + Sync {
7    fn support_filter_pushdown(
8        &self,
9        filter: &Expr,
10        db_type: RemoteDbType,
11    ) -> DFResult<TableProviderFilterPushDown>;
12
13    fn unparse_filter(&self, filter: &Expr, db_type: RemoteDbType) -> DFResult<String>;
14}
15
16#[derive(Debug)]
17pub struct DefaultUnparser {}
18
19impl Unparse for DefaultUnparser {
20    fn support_filter_pushdown(
21        &self,
22        filter: &Expr,
23        db_type: RemoteDbType,
24    ) -> DFResult<TableProviderFilterPushDown> {
25        let unparser = match db_type.create_unparser() {
26            Ok(unparser) => unparser,
27            Err(_) => return Ok(TableProviderFilterPushDown::Unsupported),
28        };
29        if unparser.expr_to_sql(filter).is_err() {
30            return Ok(TableProviderFilterPushDown::Unsupported);
31        }
32
33        let mut pushdown = TableProviderFilterPushDown::Exact;
34        filter
35            .apply(|e| {
36                if matches!(e, Expr::ScalarFunction(_)) {
37                    pushdown = TableProviderFilterPushDown::Unsupported;
38                }
39                Ok(TreeNodeRecursion::Continue)
40            })
41            .expect("won't fail");
42
43        Ok(pushdown)
44    }
45
46    fn unparse_filter(&self, filter: &Expr, db_type: RemoteDbType) -> DFResult<String> {
47        let unparser = db_type.create_unparser()?;
48        let ast = unparser.expr_to_sql(filter)?;
49        Ok(format!("{ast}"))
50    }
51}