risingwave_frontend/optimizer/plan_node/generic/
values.rs1use std::sync::Arc;
16
17use educe::Educe;
18use pretty_xmlish::{Pretty, Str, XmlNode};
19use risingwave_common::catalog::Schema;
20
21use super::{DistillUnit, GenericPlanNode};
22use crate::expr::{Expr, ExprImpl, ExprRewriter, ExprVisitor};
23use crate::optimizer::optimizer_context::OptimizerContextRef;
24use crate::optimizer::plan_node::utils::childless_record;
25use crate::optimizer::property::FunctionalDependencySet;
26
27#[derive(Debug, Clone, Educe)]
29#[educe(PartialEq, Eq, Hash)]
30pub struct Values {
31 pub rows: Arc<[Vec<ExprImpl>]>,
32 pub schema: Schema,
33 pub stream_key: Option<Vec<usize>>,
34
35 #[educe(PartialEq(ignore))]
36 #[educe(Hash(ignore))]
37 pub ctx: OptimizerContextRef,
38}
39
40impl Values {
41 pub fn new(rows: Vec<Vec<ExprImpl>>, schema: Schema, ctx: OptimizerContextRef) -> Self {
42 Self::new_inner(rows, schema, ctx, None)
43 }
44
45 pub fn new_with_stream_key(
46 rows: Vec<Vec<ExprImpl>>,
47 schema: Schema,
48 ctx: OptimizerContextRef,
49 stream_key: Vec<usize>,
50 ) -> Self {
51 Self::new_inner(rows, schema, ctx, Some(stream_key))
52 }
53
54 fn new_inner(
55 rows: Vec<Vec<ExprImpl>>,
56 schema: Schema,
57 ctx: OptimizerContextRef,
58 stream_key: Option<Vec<usize>>,
59 ) -> Self {
60 for exprs in &rows {
61 for (i, expr) in exprs.iter().enumerate() {
62 assert_eq!(schema.fields()[i].data_type(), expr.return_type());
63 }
64 }
65
66 Self {
67 rows: rows.into(),
68 schema,
69 stream_key,
70 ctx,
71 }
72 }
73
74 pub fn rows(&self) -> &[Vec<ExprImpl>] {
75 self.rows.as_ref()
76 }
77
78 pub fn rewrite_exprs(&mut self, r: &mut dyn ExprRewriter) {
79 self.rows = self
80 .rows
81 .iter()
82 .map(|exprs| {
83 exprs
84 .iter()
85 .map(|e| r.rewrite_expr(e.clone()))
86 .collect::<Vec<_>>()
87 })
88 .collect::<Vec<_>>()
89 .into();
90 }
91
92 pub fn visit_exprs(&self, v: &mut dyn ExprVisitor) {
93 self.rows.iter().flatten().for_each(|e| v.visit_expr(e));
94 }
95
96 pub fn rows_pretty<'a>(&self) -> Pretty<'a> {
97 let data = self
98 .rows()
99 .iter()
100 .map(|row| {
101 let collect = row.iter().map(Pretty::debug).collect();
102 Pretty::Array(collect)
103 })
104 .collect();
105 Pretty::Array(data)
106 }
107}
108
109impl GenericPlanNode for Values {
110 fn schema(&self) -> Schema {
111 self.schema.clone()
112 }
113
114 fn stream_key(&self) -> Option<Vec<usize>> {
115 self.stream_key.clone()
116 }
117
118 fn ctx(&self) -> OptimizerContextRef {
119 self.ctx.clone()
120 }
121
122 fn functional_dependency(&self) -> FunctionalDependencySet {
123 FunctionalDependencySet::new(self.schema.len())
124 }
125}
126
127impl DistillUnit for Values {
128 fn distill_with_name<'a>(&self, name: impl Into<Str<'a>>) -> XmlNode<'a> {
129 childless_record(
130 name,
131 vec![
132 ("rows", self.rows_pretty()),
133 ("schema", Pretty::debug(&self.schema)),
134 ],
135 )
136 }
137}