risingwave_frontend/optimizer/plan_visitor/
execution_mode_decider.rs1use super::{DefaultBehavior, Merge};
16use crate::PlanRef;
17use crate::optimizer::plan_node::{BatchLimit, BatchSeqScan, BatchValues, PlanTreeNodeUnary};
18use crate::optimizer::plan_visitor::PlanVisitor;
19
20#[derive(Debug, Clone, Default)]
21pub struct ExecutionModeDecider {}
22
23impl ExecutionModeDecider {
24 pub fn run_in_local_mode(plan: PlanRef) -> bool {
26 let mut decider = ExecutionModeDecider {};
27 decider.visit(plan)
28 }
29}
30
31impl PlanVisitor for ExecutionModeDecider {
32 type Result = bool;
33
34 type DefaultBehavior = impl DefaultBehavior<Self::Result>;
35
36 fn default_behavior() -> Self::DefaultBehavior {
37 Merge(|a, b| a & b)
38 }
39
40 fn visit_batch_seq_scan(&mut self, batch_seq_scan: &BatchSeqScan) -> bool {
45 !batch_seq_scan.scan_ranges().is_empty()
46 && batch_seq_scan
47 .scan_ranges()
48 .iter()
49 .all(|x| x.has_eq_conds() || x.two_side_bound())
50 }
51
52 fn visit_batch_values(&mut self, _batch_values: &BatchValues) -> bool {
55 true
56 }
57
58 fn visit_batch_limit(&mut self, batch_limit: &BatchLimit) -> bool {
62 if let Some(batch_seq_scan) = batch_limit.input().as_batch_seq_scan()
63 && batch_seq_scan.scan_ranges().is_empty()
64 && batch_limit.limit() + batch_limit.offset() < 100
65 {
66 true
67 } else {
68 self.visit(batch_limit.input())
69 }
70 }
71}