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