risingwave_frontend/optimizer/plan_node/
batch_iceberg_scan.rs1use std::hash::{Hash, Hasher};
16use std::rc::Rc;
17
18use pretty_xmlish::{Pretty, XmlNode};
19use risingwave_connector::source::iceberg::IcebergFileScanTask;
20use risingwave_pb::batch_plan::IcebergScanNode;
21use risingwave_pb::batch_plan::iceberg_scan_node::IcebergScanType;
22use risingwave_pb::batch_plan::plan_node::NodeBody;
23use risingwave_sqlparser::ast::AsOf;
24
25use super::batch::prelude::*;
26use super::utils::{Distill, childless_record, column_names_pretty};
27use super::{
28 BatchPlanRef as PlanRef, ExprRewritable, PlanBase, ToBatchPb, ToDistributedBatch, ToLocalBatch,
29 generic,
30};
31use crate::catalog::source_catalog::SourceCatalog;
32use crate::error::Result;
33use crate::optimizer::plan_node::expr_visitable::ExprVisitable;
34use crate::optimizer::property::{Distribution, Order};
35
36#[derive(Debug, Clone, PartialEq)]
37pub struct BatchIcebergScan {
38 pub base: PlanBase<Batch>,
39 pub core: generic::Source,
40 pub task: IcebergFileScanTask,
41 limit: Option<u64>,
42}
43
44impl Eq for BatchIcebergScan {}
45
46impl Hash for BatchIcebergScan {
47 fn hash<H: Hasher>(&self, state: &mut H) {
48 self.base.hash(state);
49 self.core.hash(state);
50 self.iceberg_scan_type().hash(state);
51 self.limit.hash(state);
52 }
53}
54
55impl BatchIcebergScan {
56 pub fn new(core: generic::Source, task: IcebergFileScanTask) -> Self {
57 let base = PlanBase::new_batch_with_core(
58 &core,
59 Distribution::Single,
61 Order::any(),
62 );
63
64 Self {
65 base,
66 core,
67 task,
68 limit: None,
69 }
70 }
71
72 pub fn clone_with_limit(&self, limit: Option<u64>) -> Self {
73 Self {
74 base: self.base.clone(),
75 core: self.core.clone(),
76 task: self.task.clone(),
77 limit,
78 }
79 }
80
81 pub fn limit(&self) -> Option<u64> {
82 self.limit
83 }
84
85 pub fn iceberg_scan_type(&self) -> IcebergScanType {
86 self.task.scan_type()
87 }
88
89 pub fn predicate(&self) -> Option<String> {
90 let predicate = self.task.predicate()?;
91 Some(predicate.to_string())
92 }
93
94 pub fn column_names(&self) -> Vec<&str> {
95 self.schema().names_str()
96 }
97
98 pub fn source_catalog(&self) -> Option<Rc<SourceCatalog>> {
99 self.core.catalog.clone()
100 }
101
102 pub fn clone_with_dist(&self) -> Self {
103 let base = self
104 .base
105 .clone_with_new_distribution(Distribution::SomeShard);
106 Self {
107 base,
108 core: self.core.clone(),
109 task: self.task.clone(),
110 limit: self.limit,
111 }
112 }
113
114 pub fn as_of(&self) -> Option<AsOf> {
115 self.core.as_of.clone()
116 }
117}
118
119impl_plan_tree_node_for_leaf! { Batch, BatchIcebergScan }
120
121impl Distill for BatchIcebergScan {
122 fn distill<'a>(&self) -> XmlNode<'a> {
123 let src = Pretty::from(self.source_catalog().unwrap().name.clone());
124 let mut fields = vec![
125 ("source", src),
126 ("columns", column_names_pretty(self.schema())),
127 (
128 "iceberg_scan_type",
129 Pretty::from(format!("{:?}", self.iceberg_scan_type())),
130 ),
131 ];
132 if let Some(predicate) = self.predicate() {
133 fields.push(("predicate", Pretty::from(predicate)));
134 }
135 if let Some(limit) = self.limit {
136 fields.push(("limit", Pretty::debug(&limit)));
137 }
138 childless_record("BatchIcebergScan", fields)
139 }
140}
141
142impl ToLocalBatch for BatchIcebergScan {
143 fn to_local(&self) -> Result<PlanRef> {
144 Ok(self.clone_with_dist().into())
145 }
146}
147
148impl ToDistributedBatch for BatchIcebergScan {
149 fn to_distributed(&self) -> Result<PlanRef> {
150 Ok(self.clone_with_dist().into())
151 }
152}
153
154impl ToBatchPb for BatchIcebergScan {
155 fn to_batch_prost_body(&self) -> NodeBody {
156 let source_catalog = self.source_catalog().unwrap();
157 let (with_properties, secret_refs) = source_catalog.with_properties.clone().into_parts();
158 NodeBody::IcebergScan(IcebergScanNode {
159 columns: self
160 .core
161 .column_catalog
162 .iter()
163 .map(|c| c.to_protobuf())
164 .collect(),
165 with_properties,
166 split: vec![],
167 secret_refs,
168 iceberg_scan_type: self.iceberg_scan_type() as i32,
169 })
170 }
171}
172
173impl ExprRewritable<Batch> for BatchIcebergScan {}
174
175impl ExprVisitable for BatchIcebergScan {}