mz_repr/optimize.rs
1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! Facilities for defining optimizer feature flags.
11
12use std::collections::BTreeMap;
13
14use proptest_derive::Arbitrary;
15use serde::{Deserialize, Serialize};
16
17/// A macro for feature flags managed by the optimizer.
18macro_rules! optimizer_feature_flags {
19 ({ $($feature:ident: $type:ty,)* }) => {
20 #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, Arbitrary)]
21 pub struct OptimizerFeatures {
22 $(pub $feature: $type),*
23 }
24
25 #[derive(Clone, Debug, Deserialize, Serialize, PartialOrd, PartialEq, Eq, Ord)]
26 pub struct OptimizerFeatureOverrides {
27 $(pub $feature: Option<$type>),*
28 }
29
30 impl Default for OptimizerFeatureOverrides {
31 fn default() -> Self {
32 Self {
33 $($feature: None),*
34 }
35 }
36 }
37
38 /// An [`OverrideFrom`] implementation that updates
39 /// [`OptimizerFeatures`] using [`OptimizerFeatureOverrides`] values.
40 impl OverrideFrom<OptimizerFeatureOverrides> for OptimizerFeatures {
41 fn override_from(mut self, overrides: &OptimizerFeatureOverrides) -> Self {
42 $(if let Some(feature_value) = overrides.$feature {
43 self.$feature = feature_value;
44 })*
45 self
46 }
47 }
48
49 /// An `OptimizerFeatureOverrides ⇒ BTreeMap<String, String>`
50 /// conversion.
51 ///
52 /// WARNING: changing the definition of item might break catalog
53 /// re-hydration for some catalog items (such as entries for `CREATE
54 /// CLUSTER ... FEATURES(...)` statements).
55 impl From<BTreeMap<String, String>> for OptimizerFeatureOverrides {
56 fn from(value: BTreeMap<String, String>) -> Self {
57 let mut overrides = OptimizerFeatureOverrides::default();
58
59 for (name, value) in value.into_iter() {
60 match name.as_str() {
61 $(stringify!($feature) => {
62 let value = Some(<$type>::decode(&value));
63 overrides.$feature = value;
64 }),*
65 _ => (), // Ignore
66 }
67 }
68
69 overrides
70 }
71 }
72
73 /// A `BTreeMap<String, String> ⇒ OptimizerFeatureOverrides` conversion.
74 ///
75 /// WARNING: changing the definition of item might break catalog
76 /// re-hydration for some catalog items (such as entries for `CREATE
77 /// CLUSTER ... FEATURES(...)` statements).
78 impl From<OptimizerFeatureOverrides> for BTreeMap<String, String> {
79 fn from(overrides: OptimizerFeatureOverrides) -> Self {
80 let mut map = BTreeMap::<String, String>::default();
81
82 $(if let Some(value) = overrides.$feature {
83 let k = stringify!($feature).into();
84 let v = value.encode();
85 map.insert(k, v);
86 };)*
87
88 map
89 }
90 }
91 };
92}
93
94optimizer_feature_flags!({
95 // Use `EquivalenceClassesWithholdingErrors` instead of raw
96 // `EquivalenceClasses` during eq prop for joins.
97 enable_eq_classes_withholding_errors: bool,
98 enable_guard_subquery_tablefunc: bool,
99 // Enable consolidation of unions that happen immediately after negate.
100 //
101 // The refinement happens in the LIR ⇒ LIR phase.
102 enable_consolidate_after_union_negate: bool,
103 // Bound from `SystemVars::enable_eager_delta_joins`.
104 enable_eager_delta_joins: bool,
105 // Enable Lattice-based fixpoint iteration on LetRec nodes in the
106 // Analysis framework.
107 enable_letrec_fixpoint_analysis: bool,
108 // Bound from `SystemVars::enable_new_outer_join_lowering`.
109 enable_new_outer_join_lowering: bool,
110 // Bound from `SystemVars::enable_reduce_mfp_fusion`.
111 enable_reduce_mfp_fusion: bool,
112 // Enable joint HIR ⇒ MIR lowering of stacks of left joins.
113 enable_variadic_left_join_lowering: bool,
114 // Enable cardinality estimation
115 enable_cardinality_estimates: bool,
116 // An exclusive upper bound on the number of results we may return from a
117 // Persist fast-path peek. Required by the `create_fast_path_plan` call in
118 // `peek::Optimizer`.
119 persist_fast_path_limit: usize,
120 // Reoptimize imported views when building and optimizing a
121 // `DataflowDescription` in the global MIR optimization phase.
122 reoptimize_imported_views: bool,
123 // See the feature flag of the same name.
124 enable_join_prioritize_arranged: bool,
125 // See the feature flag of the same name.
126 enable_projection_pushdown_after_relation_cse: bool,
127 // See the feature flag of the same name.
128 enable_less_reduce_in_eqprop: bool,
129 // See the feature flag of the same name.
130 enable_dequadratic_eqprop_map: bool,
131 // See the feature flag of the same name.
132 enable_fast_path_plan_insights: bool,
133 // See the feature flag of the same name.
134 enable_cast_elimination: bool,
135 // See the feature flag of the same name.
136 enable_case_literal_transform: bool,
137 // See the feature flag of the same name.
138 enable_simplify_quantified_comparisons: bool,
139 // See the feature flag of the same name.
140 enable_coalesce_case_transform: bool,
141});
142
143/// A trait used to implement layered config construction.
144pub trait OverrideFrom<T> {
145 /// Override the configuration represented by [`Self`] with values
146 /// from the given `layer`.
147 fn override_from(self, layer: &T) -> Self;
148}
149
150/// Overrides for `U` coming from an optional `T`.
151impl<T, U> OverrideFrom<Option<&T>> for U
152where
153 Self: OverrideFrom<T>,
154{
155 fn override_from(self, layer: &Option<&T>) -> Self {
156 match layer {
157 Some(layer) => self.override_from(layer),
158 None => self,
159 }
160 }
161}
162
163/// A trait that handles conversion of feature flags.
164trait OptimizerFeatureType {
165 fn encode(self) -> String;
166 fn decode(v: &str) -> Self;
167}
168
169/// A macro that implements [`OptimizerFeatureType`] for most common types.
170///
171/// WARNING: changing the definition of this macro might break catalog
172/// re-hydration for some catalog items (such as entries for `CREATE CLUSTER ...
173/// FEATURES(...)` statements).
174macro_rules! impl_optimizer_feature_type {
175 ($($type:ty),*) => {
176 $(
177 impl OptimizerFeatureType for $type {
178 fn encode(self) -> String {
179 self.to_string()
180 }
181
182 fn decode(v: &str) -> Self {
183 str::parse(&v).unwrap()
184 }
185 }
186 )*
187 };
188}
189
190// Implement `OptimizerFeatureType` for all types used in the
191// `optimizer_feature_flags!(...)` call above.
192impl_optimizer_feature_type![bool, usize];