risingwave_frontend/optimizer/rule/
mod.rs1use std::convert::Infallible;
18use std::ops::FromResidual;
19
20use thiserror_ext::AsReport;
21
22use super::PlanRef;
23use crate::error::RwError;
24
25pub enum ApplyResult<T = PlanRef> {
27 Ok(T),
29 NotApplicable,
32 Err(RwError),
35}
36
37impl ApplyResult {
38 pub fn unwrap(self) -> PlanRef {
40 match self {
41 ApplyResult::Ok(plan) => plan,
42 ApplyResult::NotApplicable => panic!("unwrap ApplyResult::NotApplicable"),
43 ApplyResult::Err(e) => panic!("unwrap ApplyResult::Err, error: {:?}", e.as_report()),
44 }
45 }
46}
47
48impl<T> FromResidual<Option<Infallible>> for ApplyResult<T> {
50 fn from_residual(residual: Option<Infallible>) -> Self {
51 match residual {
52 Some(i) => match i {},
53 None => Self::NotApplicable,
54 }
55 }
56}
57
58impl<T, E> FromResidual<Result<Infallible, E>> for ApplyResult<T>
60where
61 E: Into<RwError>,
62{
63 fn from_residual(residual: Result<Infallible, E>) -> Self {
64 match residual {
65 Ok(i) => match i {},
66 Err(e) => Self::Err(e.into()),
67 }
68 }
69}
70
71trait InfallibleRule: Send + Sync + Description {
75 fn apply(&self, plan: PlanRef) -> Option<PlanRef>;
80}
81use InfallibleRule as Rule;
82
83pub trait FallibleRule: Send + Sync + Description {
88 fn apply(&self, plan: PlanRef) -> ApplyResult;
95}
96
97impl<T> FallibleRule for T
98where
99 T: InfallibleRule,
100{
101 fn apply(&self, plan: PlanRef) -> ApplyResult {
102 match InfallibleRule::apply(self, plan) {
103 Some(plan) => ApplyResult::Ok(plan),
104 None => ApplyResult::NotApplicable,
105 }
106 }
107}
108
109pub trait Description {
110 fn description(&self) -> &str;
111}
112
113pub(super) type BoxedRule = Box<dyn FallibleRule>;
114
115mod logical_filter_expression_simplify_rule;
116pub use logical_filter_expression_simplify_rule::*;
117mod over_window_merge_rule;
118pub use over_window_merge_rule::*;
119mod project_join_merge_rule;
120pub use project_join_merge_rule::*;
121mod project_eliminate_rule;
122pub use project_eliminate_rule::*;
123mod project_merge_rule;
124pub use project_merge_rule::*;
125mod pull_up_correlated_predicate_rule;
126pub use pull_up_correlated_predicate_rule::*;
127mod index_delta_join_rule;
128pub use index_delta_join_rule::*;
129mod left_deep_tree_join_ordering_rule;
130pub use left_deep_tree_join_ordering_rule::*;
131mod apply_agg_transpose_rule;
132pub use apply_agg_transpose_rule::*;
133mod apply_filter_transpose_rule;
134pub use apply_filter_transpose_rule::*;
135mod apply_project_transpose_rule;
136pub use apply_project_transpose_rule::*;
137mod apply_eliminate_rule;
138pub use apply_eliminate_rule::*;
139mod translate_apply_rule;
140pub use translate_apply_rule::*;
141mod merge_multijoin_rule;
142pub use merge_multijoin_rule::*;
143mod max_one_row_eliminate_rule;
144pub use max_one_row_eliminate_rule::*;
145mod apply_join_transpose_rule;
146pub use apply_join_transpose_rule::*;
147mod apply_to_join_rule;
148pub use apply_to_join_rule::*;
149mod distinct_agg_rule;
150pub use distinct_agg_rule::*;
151mod index_selection_rule;
152pub use index_selection_rule::*;
153mod push_calculation_of_join_rule;
154pub use push_calculation_of_join_rule::*;
155mod join_commute_rule;
156mod over_window_to_agg_and_join_rule;
157pub use over_window_to_agg_and_join_rule::*;
158mod over_window_split_rule;
159pub use over_window_split_rule::*;
160mod over_window_to_topn_rule;
161pub use join_commute_rule::*;
162pub use over_window_to_topn_rule::*;
163mod union_to_distinct_rule;
164pub use union_to_distinct_rule::*;
165mod agg_project_merge_rule;
166pub use agg_project_merge_rule::*;
167mod union_merge_rule;
168pub use union_merge_rule::*;
169mod dag_to_tree_rule;
170pub use dag_to_tree_rule::*;
171mod apply_share_eliminate_rule;
172pub use apply_share_eliminate_rule::*;
173mod top_n_on_index_rule;
174pub use top_n_on_index_rule::*;
175mod stream;
176pub use stream::bushy_tree_join_ordering_rule::*;
177pub use stream::filter_with_now_to_join_rule::*;
178pub use stream::generate_series_with_now_rule::*;
179pub use stream::split_now_and_rule::*;
180pub use stream::split_now_or_rule::*;
181pub use stream::stream_project_merge_rule::*;
182mod trivial_project_to_values_rule;
183pub use trivial_project_to_values_rule::*;
184mod union_input_values_merge_rule;
185pub use union_input_values_merge_rule::*;
186mod rewrite_like_expr_rule;
187pub use rewrite_like_expr_rule::*;
188mod min_max_on_index_rule;
189pub use min_max_on_index_rule::*;
190mod always_false_filter_rule;
191pub use always_false_filter_rule::*;
192mod join_project_transpose_rule;
193pub use join_project_transpose_rule::*;
194mod limit_push_down_rule;
195pub use limit_push_down_rule::*;
196mod pull_up_hop_rule;
197pub use pull_up_hop_rule::*;
198mod apply_offset_rewriter;
199use apply_offset_rewriter::ApplyOffsetRewriter;
200mod intersect_to_semi_join_rule;
201pub use intersect_to_semi_join_rule::*;
202mod except_to_anti_join_rule;
203pub use except_to_anti_join_rule::*;
204mod intersect_merge_rule;
205pub use intersect_merge_rule::*;
206mod except_merge_rule;
207pub use except_merge_rule::*;
208mod apply_union_transpose_rule;
209pub use apply_union_transpose_rule::*;
210mod apply_dedup_transpose_rule;
211pub use apply_dedup_transpose_rule::*;
212mod project_join_separate_rule;
213pub use project_join_separate_rule::*;
214mod grouping_sets_to_expand_rule;
215pub use grouping_sets_to_expand_rule::*;
216mod apply_project_set_transpose_rule;
217pub use apply_project_set_transpose_rule::*;
218mod cross_join_eliminate_rule;
219pub use cross_join_eliminate_rule::*;
220mod table_function_to_project_set_rule;
221
222pub use table_function_to_project_set_rule::*;
223mod apply_topn_transpose_rule;
224pub use apply_topn_transpose_rule::*;
225mod apply_limit_transpose_rule;
226pub use apply_limit_transpose_rule::*;
227mod batch;
228pub use batch::batch_project_merge_rule::*;
229mod common_sub_expr_extract_rule;
230pub use common_sub_expr_extract_rule::*;
231mod apply_over_window_transpose_rule;
232pub use apply_over_window_transpose_rule::*;
233mod apply_expand_transpose_rule;
234pub use apply_expand_transpose_rule::*;
235mod expand_to_project_rule;
236pub use expand_to_project_rule::*;
237mod agg_group_by_simplify_rule;
238pub use agg_group_by_simplify_rule::*;
239mod apply_hop_window_transpose_rule;
240pub use apply_hop_window_transpose_rule::*;
241mod agg_call_merge_rule;
242pub use agg_call_merge_rule::*;
243mod add_logstore_rule;
244mod pull_up_correlated_predicate_agg_rule;
245mod source_to_iceberg_scan_rule;
246mod source_to_kafka_scan_rule;
247mod table_function_to_file_scan_rule;
248mod table_function_to_mysql_query_rule;
249mod table_function_to_postgres_query_rule;
250mod values_extract_project_rule;
251
252pub use add_logstore_rule::*;
253pub use batch::batch_iceberg_count_star::*;
254pub use batch::batch_iceberg_predicate_pushdown::*;
255pub use batch::batch_push_limit_to_scan_rule::*;
256pub use pull_up_correlated_predicate_agg_rule::*;
257pub use source_to_iceberg_scan_rule::*;
258pub use source_to_kafka_scan_rule::*;
259pub use table_function_to_file_scan_rule::*;
260pub use table_function_to_mysql_query_rule::*;
261pub use table_function_to_postgres_query_rule::*;
262pub use values_extract_project_rule::*;
263
264#[macro_export]
265macro_rules! for_all_rules {
266 ($macro:ident) => {
267 $macro! {
268 { ApplyAggTransposeRule }
269 , { ApplyFilterTransposeRule }
270 , { ApplyProjectTransposeRule }
271 , { ApplyProjectSetTransposeRule }
272 , { ApplyEliminateRule }
273 , { ApplyJoinTransposeRule }
274 , { ApplyShareEliminateRule }
275 , { ApplyToJoinRule }
276 , { MaxOneRowEliminateRule }
277 , { DistinctAggRule }
278 , { IndexDeltaJoinRule }
279 , { MergeMultiJoinRule }
280 , { ProjectEliminateRule }
281 , { ProjectJoinMergeRule }
282 , { ProjectMergeRule }
283 , { PullUpCorrelatedPredicateRule }
284 , { LeftDeepTreeJoinOrderingRule }
285 , { TranslateApplyRule }
286 , { PushCalculationOfJoinRule }
287 , { IndexSelectionRule }
288 , { OverWindowToTopNRule }
289 , { OverWindowToAggAndJoinRule }
290 , { OverWindowSplitRule }
291 , { OverWindowMergeRule }
292 , { JoinCommuteRule }
293 , { UnionToDistinctRule }
294 , { AggProjectMergeRule }
295 , { UnionMergeRule }
296 , { DagToTreeRule }
297 , { SplitNowAndRule }
298 , { SplitNowOrRule }
299 , { FilterWithNowToJoinRule }
300 , { GenerateSeriesWithNowRule }
301 , { TopNOnIndexRule }
302 , { TrivialProjectToValuesRule }
303 , { UnionInputValuesMergeRule }
304 , { RewriteLikeExprRule }
305 , { MinMaxOnIndexRule }
306 , { AlwaysFalseFilterRule }
307 , { BushyTreeJoinOrderingRule }
308 , { StreamProjectMergeRule }
309 , { LogicalFilterExpressionSimplifyRule }
310 , { JoinProjectTransposeRule }
311 , { LimitPushDownRule }
312 , { PullUpHopRule }
313 , { IntersectToSemiJoinRule }
314 , { ExceptToAntiJoinRule }
315 , { IntersectMergeRule }
316 , { ExceptMergeRule }
317 , { ApplyUnionTransposeRule }
318 , { ApplyDedupTransposeRule }
319 , { ProjectJoinSeparateRule }
320 , { GroupingSetsToExpandRule }
321 , { CrossJoinEliminateRule }
322 , { ApplyTopNTransposeRule }
323 , { TableFunctionToProjectSetRule }
324 , { TableFunctionToFileScanRule }
325 , { TableFunctionToPostgresQueryRule }
326 , { TableFunctionToMySqlQueryRule }
327 , { ApplyLimitTransposeRule }
328 , { CommonSubExprExtractRule }
329 , { BatchProjectMergeRule }
330 , { ApplyOverWindowTransposeRule }
331 , { ApplyExpandTransposeRule }
332 , { ExpandToProjectRule }
333 , { AggGroupBySimplifyRule }
334 , { ApplyHopWindowTransposeRule }
335 , { AggCallMergeRule }
336 , { ValuesExtractProjectRule }
337 , { BatchPushLimitToScanRule }
338 , { BatchIcebergPredicatePushDownRule }
339 , { BatchIcebergCountStar }
340 , { PullUpCorrelatedPredicateAggRule }
341 , { SourceToKafkaScanRule }
342 , { SourceToIcebergScanRule }
343 , { AddLogstoreRule }
344 }
345 };
346}
347
348macro_rules! impl_description {
349 ($( { $name:ident }),*) => {
350 paste::paste!{
351 $(impl Description for [<$name>] {
352 fn description(&self) -> &str {
353 stringify!([<$name>])
354 }
355 })*
356 }
357 }
358}
359
360for_all_rules! {impl_description}