risingwave_frontend/binder/relation/
share.rs1use itertools::Itertools;
16use risingwave_common::catalog::Field;
17
18use crate::binder::statement::RewriteExprsRecursive;
19use crate::binder::{BoundQuery, Relation, ShareId};
20use crate::error::{ErrorCode, Result};
21use crate::optimizer::plan_node::generic::{_CHANGELOG_ROW_ID, CHANGELOG_OP};
22
23#[derive(Debug, Clone)]
27pub enum BoundShareInput {
28 Query(BoundQuery),
29 ChangeLog {
30 relation: Relation,
31 key_indices: Option<Vec<usize>>,
33 distribution_key_indices: Option<Vec<usize>>,
34 },
35}
36impl BoundShareInput {
37 pub fn fields(&self) -> Result<Vec<(bool, Field)>> {
38 match self {
39 BoundShareInput::Query(q) => Ok(q
40 .schema()
41 .fields()
42 .iter()
43 .cloned()
44 .map(|f| (false, f))
45 .collect_vec()),
46 BoundShareInput::ChangeLog { relation: r, .. } => {
47 let (fields, _name) = if let Relation::BaseTable(bound_base_table) = r {
48 (
49 bound_base_table.table_catalog.columns().to_vec(),
50 bound_base_table.table_catalog.name().to_owned(),
51 )
52 } else if let Relation::Source(bound_source) = r {
53 (
54 bound_source.catalog.columns.clone(),
55 bound_source.catalog.name.clone(),
56 )
57 } else {
58 return Err(ErrorCode::BindError(
59 "Change log CTE must be a table or source".to_owned(),
60 )
61 .into());
62 };
63 let fields = fields
64 .into_iter()
65 .map(|x| {
66 (
67 x.is_hidden,
68 Field::with_name(x.data_type().clone(), x.name()),
69 )
70 })
71 .chain(vec![
72 (
73 false,
74 Field::with_name(
75 risingwave_common::types::DataType::Int16,
76 CHANGELOG_OP.to_owned(),
77 ),
78 ),
79 (
80 true,
81 Field::with_name(
82 risingwave_common::types::DataType::Serial,
83 _CHANGELOG_ROW_ID.to_owned(),
84 ),
85 ),
86 ])
87 .collect();
88 Ok(fields)
89 }
90 }
91 }
92}
93#[derive(Debug, Clone)]
94pub struct BoundShare {
95 pub(crate) share_id: ShareId,
96 pub(crate) input: BoundShareInput,
97}
98
99impl RewriteExprsRecursive for BoundShare {
100 fn rewrite_exprs_recursive(&mut self, rewriter: &mut impl crate::expr::ExprRewriter) {
101 match &mut self.input {
102 BoundShareInput::Query(q) => q.rewrite_exprs_recursive(rewriter),
103 BoundShareInput::ChangeLog { relation: r, .. } => r.rewrite_exprs_recursive(rewriter),
104 };
105 }
106}