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