risingwave_frontend/optimizer/rule/
values_extract_project_rule.rs1use risingwave_common::catalog::{Field, Schema};
16use risingwave_common::types::DataType;
17
18use super::{BoxedRule, Rule};
19use crate::expr::{ExprImpl, ExprVisitor};
20use crate::optimizer::PlanRef;
21use crate::optimizer::plan_node::generic::GenericPlanRef;
22use crate::optimizer::plan_node::{LogicalProject, LogicalValues};
23use crate::optimizer::plan_visitor::ExprCorrelatedIdFinder;
24
25pub struct ValuesExtractProjectRule {}
26impl Rule for ValuesExtractProjectRule {
27 fn apply(&self, plan: PlanRef) -> Option<PlanRef> {
28 let old_values: &LogicalValues = plan.as_logical_values()?;
29
30 let mut expr_correlated_id_finder = ExprCorrelatedIdFinder::default();
31
32 if old_values.rows().len() != 1 {
33 return None;
34 }
35
36 old_values.rows()[0]
37 .iter()
38 .for_each(|expr| expr_correlated_id_finder.visit_expr(expr));
39
40 if !expr_correlated_id_finder.has_correlated_input_ref() {
41 return None;
42 }
43
44 let new_values = LogicalValues::create(
45 vec![vec![ExprImpl::literal_bigint(1)]],
46 Schema::new(vec![Field::with_name(DataType::Int64, "$const")]),
47 old_values.ctx(),
48 );
49
50 Some(LogicalProject::create(
51 new_values,
52 old_values.rows()[0].clone(),
53 ))
54 }
55}
56
57impl ValuesExtractProjectRule {
58 pub fn create() -> BoxedRule {
59 Box::new(ValuesExtractProjectRule {})
60 }
61}