Skip to main content

risingwave_frontend/optimizer/plan_node/
stream_values.rs

1// Copyright 2023 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::XmlNode;
16use risingwave_pb::stream_plan::ValuesNode;
17use risingwave_pb::stream_plan::stream_node::NodeBody as ProstStreamNode;
18use risingwave_pb::stream_plan::values_node::ExprTuple;
19
20use super::stream::prelude::*;
21use super::utils::{Distill, childless_record};
22use super::{ExprRewritable, PlanBase, StreamNode, StreamPlanRef as PlanRef, generic};
23use crate::expr::{Expr, ExprImpl, ExprVisitor};
24use crate::optimizer::plan_node::expr_visitable::ExprVisitable;
25use crate::optimizer::property::{Distribution, MonotonicityMap, WatermarkColumns};
26use crate::stream_fragmenter::BuildFragmentGraphState;
27
28/// `StreamValues` implements `LogicalValues.to_stream()`
29#[derive(Debug, Clone, PartialEq, Eq, Hash)]
30pub struct StreamValues {
31    pub base: PlanBase<Stream>,
32    core: generic::Values,
33}
34
35impl_plan_tree_node_for_leaf! { Stream, StreamValues }
36
37impl StreamValues {
38    /// `StreamValues` should enforce `Distribution::Single`
39    pub fn new(core: generic::Values) -> Self {
40        let base = PlanBase::new_stream_with_core(
41            &core,
42            Distribution::Single,
43            StreamKind::AppendOnly,
44            false,
45            WatermarkColumns::new(),
46            MonotonicityMap::new(),
47        );
48        Self { base, core }
49    }
50
51    fn row_to_protobuf(&self, row: &[ExprImpl]) -> ExprTuple {
52        let cells = row.iter().map(|x| x.to_expr_proto()).collect();
53        ExprTuple { cells }
54    }
55}
56
57impl Distill for StreamValues {
58    fn distill<'a>(&self) -> XmlNode<'a> {
59        let data = self.core.rows_pretty();
60        childless_record("StreamValues", vec![("rows", data)])
61    }
62}
63
64impl StreamNode for StreamValues {
65    fn to_stream_prost_body(&self, _state: &mut BuildFragmentGraphState) -> ProstStreamNode {
66        ProstStreamNode::Values(Box::new(ValuesNode {
67            tuples: self
68                .core
69                .rows()
70                .iter()
71                .map(|row| self.row_to_protobuf(row))
72                .collect(),
73            fields: self
74                .core
75                .schema
76                .fields()
77                .iter()
78                .map(|f| f.to_prost())
79                .collect(),
80        }))
81    }
82}
83
84impl ExprRewritable<Stream> for StreamValues {
85    fn has_rewritable_expr(&self) -> bool {
86        true
87    }
88
89    fn rewrite_exprs(&self, r: &mut dyn crate::expr::ExprRewriter) -> PlanRef {
90        let mut core = self.core.clone();
91        core.rewrite_exprs(r);
92        Self::new(core).into()
93    }
94}
95
96impl ExprVisitable for StreamValues {
97    fn visit_exprs(&self, v: &mut dyn ExprVisitor) {
98        self.core.visit_exprs(v);
99    }
100}