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