risingwave_frontend/optimizer/plan_node/
batch_sys_seq_scan.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use pretty_xmlish::{Pretty, XmlNode};
16use risingwave_pb::batch_plan::SysRowSeqScanNode;
17use risingwave_pb::batch_plan::plan_node::NodeBody;
18use risingwave_pb::plan_common::PbColumnDesc;
19
20use super::batch::prelude::*;
21use super::utils::{Distill, childless_record};
22use super::{
23    BatchPlanRef as PlanRef, ExprRewritable, PlanBase, ToBatchPb, ToDistributedBatch, generic,
24};
25use crate::error::Result;
26use crate::optimizer::plan_node::ToLocalBatch;
27use crate::optimizer::plan_node::expr_visitable::ExprVisitable;
28use crate::optimizer::property::{Distribution, DistributionDisplay, Order};
29
30/// `BatchSysSeqScan` implements [`super::LogicalSysScan`] to scan from a row-oriented table
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32pub struct BatchSysSeqScan {
33    pub base: PlanBase<Batch>,
34    core: generic::SysScan,
35}
36
37impl BatchSysSeqScan {
38    fn new_inner(core: generic::SysScan) -> Self {
39        let base = PlanBase::new_batch_with_core(&core, Distribution::Single, Order::any());
40
41        Self { base, core }
42    }
43
44    pub fn new(core: generic::SysScan) -> Self {
45        Self::new_inner(core)
46    }
47
48    fn clone_with_dist(&self) -> Self {
49        Self::new_inner(self.core.clone())
50    }
51
52    /// Get a reference to the batch seq scan's logical.
53    #[must_use]
54    pub fn core(&self) -> &generic::SysScan {
55        &self.core
56    }
57}
58
59impl_plan_tree_node_for_leaf! { Batch, BatchSysSeqScan }
60
61impl Distill for BatchSysSeqScan {
62    fn distill<'a>(&self) -> XmlNode<'a> {
63        let verbose = self.base.ctx().is_explain_verbose();
64        let mut vec = Vec::with_capacity(4);
65        vec.push(("table", Pretty::from(self.core.table.name.clone())));
66        vec.push(("columns", self.core.columns_pretty(verbose)));
67
68        if verbose {
69            let dist = Pretty::display(&DistributionDisplay {
70                distribution: self.distribution(),
71                input_schema: self.base.schema(),
72            });
73            vec.push(("distribution", dist));
74        }
75
76        childless_record("BatchSysScan", vec)
77    }
78}
79
80impl ToDistributedBatch for BatchSysSeqScan {
81    fn to_distributed(&self) -> Result<PlanRef> {
82        Ok(self.clone_with_dist().into())
83    }
84}
85
86impl ToBatchPb for BatchSysSeqScan {
87    fn to_batch_prost_body(&self) -> NodeBody {
88        let column_descs = self
89            .core
90            .column_descs()
91            .iter()
92            .map(PbColumnDesc::from)
93            .collect();
94        NodeBody::SysRowSeqScan(SysRowSeqScanNode {
95            table_id: self.core.table.id.table_id,
96            column_descs,
97        })
98    }
99}
100
101impl ToLocalBatch for BatchSysSeqScan {
102    fn to_local(&self) -> Result<PlanRef> {
103        Ok(Self::new_inner(self.core.clone()).into())
104    }
105}
106
107impl ExprRewritable<Batch> for BatchSysSeqScan {}
108
109impl ExprVisitable for BatchSysSeqScan {}