risingwave_frontend/optimizer/plan_node/
logical_table_function.rs1use super::utils::impl_distill_by_unit;
16use super::{
17 ColPrunable, ExprRewritable, Logical, LogicalFilter, LogicalPlanRef as PlanRef, LogicalProject,
18 PlanBase, PredicatePushdown, ToBatch, ToStream, generic,
19};
20use crate::error::Result;
21use crate::expr::{ExprRewriter, ExprVisitor, TableFunction};
22use crate::optimizer::optimizer_context::OptimizerContextRef;
23use crate::optimizer::plan_node::expr_visitable::ExprVisitable;
24use crate::optimizer::plan_node::{
25 ColumnPruningContext, PredicatePushdownContext, RewriteStreamContext, ToStreamContext,
26};
27use crate::utils::{ColIndexMapping, Condition};
28
29#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub struct LogicalTableFunction {
34 pub base: PlanBase<Logical>,
35 core: generic::TableFunction,
36}
37
38impl LogicalTableFunction {
39 fn with_core(core: generic::TableFunction) -> Self {
40 let base = PlanBase::new_logical_with_core(&core);
41 Self { base, core }
42 }
43
44 pub fn new(
46 table_function: TableFunction,
47 with_ordinality: bool,
48 ctx: OptimizerContextRef,
49 ) -> Self {
50 Self::with_core(generic::TableFunction::new(
51 table_function,
52 with_ordinality,
53 ctx,
54 ))
55 }
56
57 pub fn table_function(&self) -> &TableFunction {
58 &self.core.table_function
59 }
60
61 pub fn with_ordinality(&self) -> bool {
62 self.core.with_ordinality
63 }
64}
65
66impl_plan_tree_node_for_leaf! { Logical, LogicalTableFunction }
67impl_distill_by_unit!(LogicalTableFunction, core, "LogicalTableFunction");
68
69impl ColPrunable for LogicalTableFunction {
70 fn prune_col(&self, required_cols: &[usize], _ctx: &mut ColumnPruningContext) -> PlanRef {
71 LogicalProject::with_out_col_idx(self.clone().into(), required_cols.iter().copied()).into()
73 }
74}
75
76impl ExprRewritable<Logical> for LogicalTableFunction {
77 fn has_rewritable_expr(&self) -> bool {
78 true
79 }
80
81 fn rewrite_exprs(&self, r: &mut dyn ExprRewriter) -> PlanRef {
82 let mut core = self.core.clone();
83 core.rewrite_exprs(r);
84 Self::with_core(core).into()
85 }
86}
87
88impl ExprVisitable for LogicalTableFunction {
89 fn visit_exprs(&self, v: &mut dyn ExprVisitor) {
90 self.core.visit_exprs(v);
91 }
92}
93
94impl PredicatePushdown for LogicalTableFunction {
95 fn predicate_pushdown(
96 &self,
97 predicate: Condition,
98 _ctx: &mut PredicatePushdownContext,
99 ) -> PlanRef {
100 LogicalFilter::create(self.clone().into(), predicate)
101 }
102}
103
104impl ToBatch for LogicalTableFunction {
105 fn to_batch(&self) -> Result<crate::optimizer::plan_node::BatchPlanRef> {
106 unreachable!("TableFunction should be converted to ProjectSet")
107 }
108}
109
110impl ToStream for LogicalTableFunction {
111 fn to_stream(
112 &self,
113 _ctx: &mut ToStreamContext,
114 ) -> Result<crate::optimizer::plan_node::StreamPlanRef> {
115 unreachable!("TableFunction should be converted to ProjectSet")
116 }
117
118 fn logical_rewrite_for_stream(
119 &self,
120 _ctx: &mut RewriteStreamContext,
121 ) -> Result<(PlanRef, ColIndexMapping)> {
122 unreachable!("TableFunction should be converted to ProjectSet")
123 }
124}