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_reduce_reduction: bool,
125 // See the feature flag of the same name.
126 enable_join_prioritize_arranged: bool,
127 // See the feature flag of the same name.
128 enable_projection_pushdown_after_relation_cse: bool,
129 // See the feature flag of the same name.
130 enable_less_reduce_in_eqprop: bool,
131 // See the feature flag of the same name.
132 enable_dequadratic_eqprop_map: bool,
133 enable_fast_path_plan_insights: bool,
134});
135
136/// A trait used to implement layered config construction.
137pub trait OverrideFrom<T> {
138 /// Override the configuration represented by [`Self`] with values
139 /// from the given `layer`.
140 fn override_from(self, layer: &T) -> Self;
141}
142
143/// Overrides for `U` coming from an optional `T`.
144impl<T, U> OverrideFrom<Option<&T>> for U
145where
146 Self: OverrideFrom<T>,
147{
148 fn override_from(self, layer: &Option<&T>) -> Self {
149 match layer {
150 Some(layer) => self.override_from(layer),
151 None => self,
152 }
153 }
154}
155
156/// A trait that handles conversion of feature flags.
157trait OptimizerFeatureType {
158 fn encode(self) -> String;
159 fn decode(v: &str) -> Self;
160}
161
162/// A macro that implements [`OptimizerFeatureType`] for most common types.
163///
164/// WARNING: changing the definition of this macro might break catalog
165/// re-hydration for some catalog items (such as entries for `CREATE CLUSTER ...
166/// FEATURES(...)` statements).
167macro_rules! impl_optimizer_feature_type {
168 ($($type:ty),*) => {
169 $(
170 impl OptimizerFeatureType for $type {
171 fn encode(self) -> String {
172 self.to_string()
173 }
174
175 fn decode(v: &str) -> Self {
176 str::parse(&v).unwrap()
177 }
178 }
179 )*
180 };
181}
182
183// Implement `OptimizerFeatureType` for all types used in the
184// `optimizer_feature_flags!(...)` call above.
185impl_optimizer_feature_type![bool, usize];