mz_sql/session/vars/
definitions.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
10use std::borrow::Cow;
11use std::str::FromStr;
12use std::sync::Arc;
13use std::sync::LazyLock;
14use std::time::Duration;
15
16use chrono::{DateTime, Utc};
17use derivative::Derivative;
18use mz_adapter_types::timestamp_oracle::{
19    DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_MAX_SIZE, DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_MAX_WAIT,
20    DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_TTL, DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_TTL_STAGGER,
21};
22use mz_ore::cast::{self, CastFrom};
23use mz_repr::adt::numeric::Numeric;
24use mz_repr::adt::timestamp::CheckedTimestamp;
25use mz_repr::bytes::ByteSize;
26use mz_repr::optimize::OptimizerFeatures;
27use mz_sql_parser::ast::Ident;
28use mz_sql_parser::ident;
29use mz_storage_types::parameters::REPLICA_STATUS_HISTORY_RETENTION_WINDOW_DEFAULT;
30use mz_storage_types::parameters::{
31    DEFAULT_PG_SOURCE_CONNECT_TIMEOUT, DEFAULT_PG_SOURCE_TCP_CONFIGURE_SERVER,
32    DEFAULT_PG_SOURCE_TCP_KEEPALIVES_IDLE, DEFAULT_PG_SOURCE_TCP_KEEPALIVES_INTERVAL,
33    DEFAULT_PG_SOURCE_TCP_KEEPALIVES_RETRIES, DEFAULT_PG_SOURCE_TCP_USER_TIMEOUT,
34    DEFAULT_PG_SOURCE_WAL_SENDER_TIMEOUT, STORAGE_MANAGED_COLLECTIONS_BATCH_DURATION_DEFAULT,
35};
36use mz_tracing::{CloneableEnvFilter, SerializableDirective};
37use uncased::UncasedStr;
38
39use crate::session::user::{SUPPORT_USER, SYSTEM_USER, User};
40use crate::session::vars::constraints::{
41    BYTESIZE_AT_LEAST_1MB, DomainConstraint, NUMERIC_BOUNDED_0_1_INCLUSIVE, NUMERIC_NON_NEGATIVE,
42    ValueConstraint,
43};
44use crate::session::vars::errors::VarError;
45use crate::session::vars::polyfill::{LazyValueFn, lazy_value, value};
46use crate::session::vars::value::{
47    ClientEncoding, ClientSeverity, DEFAULT_DATE_STYLE, Failpoints, IntervalStyle, IsolationLevel,
48    TimeZone, Value,
49};
50use crate::session::vars::{FeatureFlag, Var, VarInput, VarParseError};
51use crate::{DEFAULT_SCHEMA, WEBHOOK_CONCURRENCY_LIMIT};
52
53/// Definition of a variable.
54#[derive(Clone, Derivative)]
55#[derivative(Debug)]
56pub struct VarDefinition {
57    /// Name of the variable, case-insensitive matching.
58    pub name: &'static UncasedStr,
59    /// Description of the variable.
60    pub description: &'static str,
61    /// Is the variable visible to users, when false only visible to system users.
62    pub user_visible: bool,
63
64    /// Default compiled in value for this variable.
65    pub value: VarDefaultValue,
66    /// Constraint that must be upheld for this variable to be valid.
67    pub constraint: Option<ValueConstraint>,
68    /// When set, prevents getting or setting the variable unless the specified
69    /// feature flag is enabled.
70    pub require_feature_flag: Option<&'static FeatureFlag>,
71
72    /// Method to parse [`VarInput`] into a type that implements [`Value`].
73    ///
74    /// The reason `parse` exists as a function pointer is because we want to achieve two things:
75    ///   1. `VarDefinition` has no generic parameters.
76    ///   2. `Value::parse` returns an instance of `Self`.
77    /// `VarDefinition` holds a `dyn Value`, but `Value::parse` is not object safe because it
78    /// returns `Self`, so we can't call that method. We could change `Value::parse` to return a
79    /// `Box<dyn Value>` making it object safe, but that creates a footgun where it's possible for
80    /// `Value::parse` to return a type that isn't `Self`, e.g. `<String as Value>::parse` could
81    /// return a `usize`!
82    ///
83    /// So to prevent making `VarDefinition` generic over some type `V: Value`, but also defining
84    /// `Value::parse` as returning `Self`, we store a static function pointer to the `parse`
85    /// implementation of our default value.
86    #[derivative(Debug = "ignore")]
87    parse: fn(VarInput) -> Result<Box<dyn Value>, VarParseError>,
88    /// Returns a human readable name for the type of this variable. We store this as a static
89    /// function pointer for the same reason as `parse`.
90    #[derivative(Debug = "ignore")]
91    type_name: fn() -> Cow<'static, str>,
92}
93static_assertions::assert_impl_all!(VarDefinition: Send, Sync);
94
95impl VarDefinition {
96    /// Create a new [`VarDefinition`] in a const context with a value known at compile time.
97    pub const fn new<V: Value>(
98        name: &'static str,
99        value: &'static V,
100        description: &'static str,
101        user_visible: bool,
102    ) -> Self {
103        VarDefinition {
104            name: UncasedStr::new(name),
105            description,
106            value: VarDefaultValue::Static(value),
107            user_visible,
108            parse: V::parse_dyn_value,
109            type_name: V::type_name,
110            constraint: None,
111            require_feature_flag: None,
112        }
113    }
114
115    /// Create a new [`VarDefinition`] in a const context with a lazily evaluated value.
116    pub const fn new_lazy<V: Value, L: LazyValueFn<V>>(
117        name: &'static str,
118        _value: L,
119        description: &'static str,
120        user_visible: bool,
121    ) -> Self {
122        VarDefinition {
123            name: UncasedStr::new(name),
124            description,
125            value: VarDefaultValue::Lazy(L::LAZY_VALUE_FN),
126            user_visible,
127            parse: V::parse_dyn_value,
128            type_name: V::type_name,
129            constraint: None,
130            require_feature_flag: None,
131        }
132    }
133
134    /// Create a new [`VarDefinition`] with a value known at runtime.
135    pub fn new_runtime<V: Value>(
136        name: &'static str,
137        value: V,
138        description: &'static str,
139        user_visible: bool,
140    ) -> Self {
141        VarDefinition {
142            name: UncasedStr::new(name),
143            description,
144            value: VarDefaultValue::Runtime(Arc::new(value)),
145            user_visible,
146            parse: V::parse_dyn_value,
147            type_name: V::type_name,
148            constraint: None,
149            require_feature_flag: None,
150        }
151    }
152
153    /// TODO(parkmycar): Refactor this method onto a `VarDefinitionBuilder` that would allow us to
154    /// constrain `V` here to be the same `V` used in [`VarDefinition::new`].
155    pub const fn with_constraint<V: Value, D: DomainConstraint<Value = V>>(
156        mut self,
157        constraint: &'static D,
158    ) -> Self {
159        self.constraint = Some(ValueConstraint::Domain(constraint));
160        self
161    }
162
163    pub const fn fixed(mut self) -> Self {
164        self.constraint = Some(ValueConstraint::Fixed);
165        self
166    }
167
168    pub const fn read_only(mut self) -> Self {
169        self.constraint = Some(ValueConstraint::ReadOnly);
170        self
171    }
172
173    pub const fn with_feature_flag(mut self, feature_flag: &'static FeatureFlag) -> Self {
174        self.require_feature_flag = Some(feature_flag);
175        self
176    }
177
178    pub fn parse(&self, input: VarInput) -> Result<Box<dyn Value>, VarError> {
179        (self.parse)(input).map_err(|err| err.into_var_error(self))
180    }
181
182    pub fn default_value(&self) -> &'_ dyn Value {
183        self.value.value()
184    }
185}
186
187impl Var for VarDefinition {
188    fn name(&self) -> &'static str {
189        self.name.as_str()
190    }
191
192    fn value(&self) -> String {
193        self.default_value().format()
194    }
195
196    fn description(&self) -> &'static str {
197        self.description
198    }
199
200    fn type_name(&self) -> Cow<'static, str> {
201        (self.type_name)()
202    }
203
204    fn visible(&self, user: &User, system_vars: &super::SystemVars) -> Result<(), VarError> {
205        if !self.user_visible && user != &*SYSTEM_USER && user != &*SUPPORT_USER {
206            Err(VarError::UnknownParameter(self.name().to_string()))
207        } else if self.is_unsafe() && !system_vars.allow_unsafe() {
208            Err(VarError::RequiresUnsafeMode(self.name()))
209        } else {
210            if let Some(flag) = self.require_feature_flag {
211                flag.require(system_vars)?;
212            }
213
214            Ok(())
215        }
216    }
217}
218
219/// The kinds of compiled in default values that can be used with [`VarDefinition`].
220#[derive(Clone, Debug)]
221pub enum VarDefaultValue {
222    /// Static that can be evaluated at compile time.
223    Static(&'static dyn Value),
224    /// Lazy value that is defined at compile time, but created at runtime.
225    Lazy(fn() -> &'static dyn Value),
226    /// Value created at runtime. Note: This is generally an escape hatch.
227    Runtime(Arc<dyn Value>),
228}
229
230impl VarDefaultValue {
231    pub fn value(&self) -> &'_ dyn Value {
232        match self {
233            VarDefaultValue::Static(s) => *s,
234            VarDefaultValue::Lazy(l) => (l)(),
235            VarDefaultValue::Runtime(r) => r.as_ref(),
236        }
237    }
238}
239
240// We pretend to be Postgres v9.5.0, which is also what CockroachDB pretends to
241// be. Too new and some clients will emit a "server too new" warning. Too old
242// and some clients will fall back to legacy code paths. v9.5.0 empirically
243// seems to be a good compromise.
244
245/// The major version of PostgreSQL that Materialize claims to be.
246pub const SERVER_MAJOR_VERSION: u8 = 9;
247
248/// The minor version of PostgreSQL that Materialize claims to be.
249pub const SERVER_MINOR_VERSION: u8 = 5;
250
251/// The patch version of PostgreSQL that Materialize claims to be.
252pub const SERVER_PATCH_VERSION: u8 = 0;
253
254/// The name of the default database that Materialize uses.
255pub const DEFAULT_DATABASE_NAME: &str = "materialize";
256
257pub static APPLICATION_NAME: VarDefinition = VarDefinition::new(
258    "application_name",
259    value!(String; String::new()),
260    "Sets the application name to be reported in statistics and logs (PostgreSQL).",
261    true,
262);
263
264pub static CLIENT_ENCODING: VarDefinition = VarDefinition::new(
265    "client_encoding",
266    value!(ClientEncoding; ClientEncoding::Utf8),
267    "Sets the client's character set encoding (PostgreSQL).",
268    true,
269);
270
271pub static CLIENT_MIN_MESSAGES: VarDefinition = VarDefinition::new(
272    "client_min_messages",
273    value!(ClientSeverity; ClientSeverity::Notice),
274    "Sets the message levels that are sent to the client (PostgreSQL).",
275    true,
276);
277
278pub static CLUSTER: VarDefinition = VarDefinition::new_lazy(
279    "cluster",
280    lazy_value!(String; || "quickstart".to_string()),
281    "Sets the current cluster (Materialize).",
282    true,
283);
284
285pub static CLUSTER_REPLICA: VarDefinition = VarDefinition::new(
286    "cluster_replica",
287    value!(Option<String>; None),
288    "Sets a target cluster replica for SELECT queries (Materialize).",
289    true,
290);
291
292pub static CURRENT_OBJECT_MISSING_WARNINGS: VarDefinition = VarDefinition::new(
293    "current_object_missing_warnings",
294    value!(bool; true),
295    "Whether to emit warnings when the current database, schema, or cluster is missing (Materialize).",
296    true,
297);
298
299pub static DATABASE: VarDefinition = VarDefinition::new_lazy(
300    "database",
301    lazy_value!(String; || DEFAULT_DATABASE_NAME.to_string()),
302    "Sets the current database (CockroachDB).",
303    true,
304);
305
306pub static DATE_STYLE: VarDefinition = VarDefinition::new(
307    // DateStyle has nonstandard capitalization for historical reasons.
308    "DateStyle",
309    &DEFAULT_DATE_STYLE,
310    "Sets the display format for date and time values (PostgreSQL).",
311    true,
312);
313
314pub static DEFAULT_CLUSTER_REPLICATION_FACTOR: VarDefinition = VarDefinition::new(
315    "default_cluster_replication_factor",
316    value!(u32; 1),
317    "Default cluster replication factor (Materialize).",
318    true,
319);
320
321pub static EXTRA_FLOAT_DIGITS: VarDefinition = VarDefinition::new(
322    "extra_float_digits",
323    value!(i32; 3),
324    "Adjusts the number of digits displayed for floating-point values (PostgreSQL).",
325    true,
326);
327
328pub static FAILPOINTS: VarDefinition = VarDefinition::new(
329    "failpoints",
330    value!(Failpoints; Failpoints),
331    "Allows failpoints to be dynamically activated.",
332    true,
333);
334
335pub static INTEGER_DATETIMES: VarDefinition = VarDefinition::new(
336    "integer_datetimes",
337    value!(bool; true),
338    "Reports whether the server uses 64-bit-integer dates and times (PostgreSQL).",
339    true,
340)
341.fixed();
342
343pub static INTERVAL_STYLE: VarDefinition = VarDefinition::new(
344    // IntervalStyle has nonstandard capitalization for historical reasons.
345    "IntervalStyle",
346    value!(IntervalStyle; IntervalStyle::Postgres),
347    "Sets the display format for interval values (PostgreSQL).",
348    true,
349);
350
351pub const MZ_VERSION_NAME: &UncasedStr = UncasedStr::new("mz_version");
352pub const IS_SUPERUSER_NAME: &UncasedStr = UncasedStr::new("is_superuser");
353
354// Schema can be used an alias for a search path with a single element.
355pub const SCHEMA_ALIAS: &UncasedStr = UncasedStr::new("schema");
356pub static SEARCH_PATH: VarDefinition = VarDefinition::new_lazy(
357    "search_path",
358    lazy_value!(Vec<Ident>; || vec![ident!(DEFAULT_SCHEMA)]),
359    "Sets the schema search order for names that are not schema-qualified (PostgreSQL).",
360    true,
361);
362
363pub static STATEMENT_TIMEOUT: VarDefinition = VarDefinition::new(
364    "statement_timeout",
365    value!(Duration; Duration::from_secs(60)),
366    "Sets the maximum allowed duration of INSERT...SELECT, UPDATE, and DELETE operations. \
367    If this value is specified without units, it is taken as milliseconds.",
368    true,
369);
370
371pub static IDLE_IN_TRANSACTION_SESSION_TIMEOUT: VarDefinition = VarDefinition::new(
372    "idle_in_transaction_session_timeout",
373    value!(Duration; Duration::from_secs(60 * 2)),
374    "Sets the maximum allowed duration that a session can sit idle in a transaction before \
375    being terminated. If this value is specified without units, it is taken as milliseconds. \
376    A value of zero disables the timeout (PostgreSQL).",
377    true,
378);
379
380pub static SERVER_VERSION: VarDefinition = VarDefinition::new_lazy(
381    "server_version",
382    lazy_value!(String; || {
383        format!("{SERVER_MAJOR_VERSION}.{SERVER_MINOR_VERSION}.{SERVER_PATCH_VERSION}")
384    }),
385    "Shows the PostgreSQL compatible server version (PostgreSQL).",
386    true,
387)
388.read_only();
389
390pub static SERVER_VERSION_NUM: VarDefinition = VarDefinition::new(
391    "server_version_num",
392    value!(i32; (cast::u8_to_i32(SERVER_MAJOR_VERSION) * 10_000)
393        + (cast::u8_to_i32(SERVER_MINOR_VERSION) * 100)
394        + cast::u8_to_i32(SERVER_PATCH_VERSION)),
395    "Shows the PostgreSQL compatible server version as an integer (PostgreSQL).",
396    true,
397)
398.read_only();
399
400pub static SQL_SAFE_UPDATES: VarDefinition = VarDefinition::new(
401    "sql_safe_updates",
402    value!(bool; false),
403    "Prohibits SQL statements that may be overly destructive (CockroachDB).",
404    true,
405);
406
407pub static STANDARD_CONFORMING_STRINGS: VarDefinition = VarDefinition::new(
408    "standard_conforming_strings",
409    value!(bool; true),
410    "Causes '...' strings to treat backslashes literally (PostgreSQL).",
411    true,
412)
413.fixed();
414
415pub static TIMEZONE: VarDefinition = VarDefinition::new(
416    // TimeZone has nonstandard capitalization for historical reasons.
417    "TimeZone",
418    value!(TimeZone; TimeZone::UTC),
419    "Sets the time zone for displaying and interpreting time stamps (PostgreSQL).",
420    true,
421);
422
423pub const TRANSACTION_ISOLATION_VAR_NAME: &str = "transaction_isolation";
424pub static TRANSACTION_ISOLATION: VarDefinition = VarDefinition::new(
425    TRANSACTION_ISOLATION_VAR_NAME,
426    value!(IsolationLevel; IsolationLevel::StrictSerializable),
427    "Sets the current transaction's isolation level (PostgreSQL).",
428    true,
429);
430
431pub static MAX_KAFKA_CONNECTIONS: VarDefinition = VarDefinition::new(
432    "max_kafka_connections",
433    value!(u32; 1000),
434    "The maximum number of Kafka connections in the region, across all schemas (Materialize).",
435    true,
436);
437
438pub static MAX_POSTGRES_CONNECTIONS: VarDefinition = VarDefinition::new(
439    "max_postgres_connections",
440    value!(u32; 1000),
441    "The maximum number of PostgreSQL connections in the region, across all schemas (Materialize).",
442    true,
443);
444
445pub static MAX_MYSQL_CONNECTIONS: VarDefinition = VarDefinition::new(
446    "max_mysql_connections",
447    value!(u32; 1000),
448    "The maximum number of MySQL connections in the region, across all schemas (Materialize).",
449    true,
450);
451
452pub static MAX_SQL_SERVER_CONNECTIONS: VarDefinition = VarDefinition::new(
453    "max_sql_server_connections",
454    value!(u32; 1000),
455    "The maximum number of SQL Server connections in the region, across all schemas (Materialize).",
456    true,
457);
458
459pub static MAX_AWS_PRIVATELINK_CONNECTIONS: VarDefinition = VarDefinition::new(
460    "max_aws_privatelink_connections",
461    value!(u32; 0),
462    "The maximum number of AWS PrivateLink connections in the region, across all schemas (Materialize).",
463    true,
464);
465
466pub static MAX_TABLES: VarDefinition = VarDefinition::new(
467    "max_tables",
468    value!(u32; 200),
469    "The maximum number of tables in the region, across all schemas (Materialize).",
470    true,
471);
472
473pub static MAX_SOURCES: VarDefinition = VarDefinition::new(
474    "max_sources",
475    value!(u32; 200),
476    "The maximum number of sources in the region, across all schemas (Materialize).",
477    true,
478);
479
480pub static MAX_SINKS: VarDefinition = VarDefinition::new(
481    "max_sinks",
482    value!(u32; 25),
483    "The maximum number of sinks in the region, across all schemas (Materialize).",
484    true,
485);
486
487pub static MAX_MATERIALIZED_VIEWS: VarDefinition = VarDefinition::new(
488    "max_materialized_views",
489    value!(u32; 100),
490    "The maximum number of materialized views in the region, across all schemas (Materialize).",
491    true,
492);
493
494pub static MAX_CLUSTERS: VarDefinition = VarDefinition::new(
495    "max_clusters",
496    value!(u32; 10),
497    "The maximum number of clusters in the region (Materialize).",
498    true,
499);
500
501pub static MAX_REPLICAS_PER_CLUSTER: VarDefinition = VarDefinition::new(
502    "max_replicas_per_cluster",
503    value!(u32; 5),
504    "The maximum number of replicas of a single cluster (Materialize).",
505    true,
506);
507
508pub static MAX_CREDIT_CONSUMPTION_RATE: VarDefinition = VarDefinition::new_lazy(
509    "max_credit_consumption_rate",
510    lazy_value!(Numeric; || 1024.into()),
511    "The maximum rate of credit consumption in a region. Credits are consumed based on the size of cluster replicas in use (Materialize).",
512    true,
513)
514.with_constraint(&NUMERIC_NON_NEGATIVE);
515
516pub static MAX_DATABASES: VarDefinition = VarDefinition::new(
517    "max_databases",
518    value!(u32; 1000),
519    "The maximum number of databases in the region (Materialize).",
520    true,
521);
522
523pub static MAX_SCHEMAS_PER_DATABASE: VarDefinition = VarDefinition::new(
524    "max_schemas_per_database",
525    value!(u32; 1000),
526    "The maximum number of schemas in a database (Materialize).",
527    true,
528);
529
530pub static MAX_OBJECTS_PER_SCHEMA: VarDefinition = VarDefinition::new(
531    "max_objects_per_schema",
532    value!(u32; 1000),
533    "The maximum number of objects in a schema (Materialize).",
534    true,
535);
536
537pub static MAX_SECRETS: VarDefinition = VarDefinition::new(
538    "max_secrets",
539    value!(u32; 100),
540    "The maximum number of secrets in the region, across all schemas (Materialize).",
541    true,
542);
543
544pub static MAX_ROLES: VarDefinition = VarDefinition::new(
545    "max_roles",
546    value!(u32; 1000),
547    "The maximum number of roles in the region (Materialize).",
548    true,
549);
550
551pub static MAX_CONTINUAL_TASKS: VarDefinition = VarDefinition::new(
552    "max_continual_tasks",
553    value!(u32; 100),
554    "The maximum number of continual tasks in the region, across all schemas (Materialize).",
555    true,
556);
557
558pub static MAX_NETWORK_POLICIES: VarDefinition = VarDefinition::new(
559    "max_network_policies",
560    value!(u32; 25),
561    "The maximum number of network policies in the region.",
562    true,
563);
564
565pub static MAX_RULES_PER_NETWORK_POLICY: VarDefinition = VarDefinition::new(
566    "max_rules_per_network_policy",
567    value!(u32; 25),
568    "The maximum number of rules per network policies.",
569    true,
570);
571
572// Cloud environmentd is configured with 4 GiB of RAM, so 1 GiB is a good heuristic for a single
573// query.
574//
575// We constrain this parameter to a minimum of 1MB, to avoid accidental usage of values that will
576// interfere with queries executed by the system itself.
577//
578// TODO(jkosh44) Eventually we want to be able to return arbitrary sized results.
579pub static MAX_RESULT_SIZE: VarDefinition = VarDefinition::new(
580    "max_result_size",
581    value!(ByteSize; ByteSize::gb(1)),
582    "The maximum size in bytes for an internal query result (Materialize).",
583    true,
584)
585.with_constraint(&BYTESIZE_AT_LEAST_1MB);
586
587pub static MAX_QUERY_RESULT_SIZE: VarDefinition = VarDefinition::new(
588    "max_query_result_size",
589    value!(ByteSize; ByteSize::gb(1)),
590    "The maximum size in bytes for a single query's result (Materialize).",
591    true,
592);
593
594pub static MAX_COPY_FROM_SIZE: VarDefinition = VarDefinition::new(
595    "max_copy_from_size",
596    // 1 GiB, this limit is noted in the docs, if you change it make sure to update our docs.
597    value!(u32; 1_073_741_824),
598    "The maximum size in bytes we buffer for COPY FROM statements (Materialize).",
599    true,
600);
601
602pub static MAX_IDENTIFIER_LENGTH: VarDefinition = VarDefinition::new(
603    "max_identifier_length",
604    value!(usize; mz_sql_lexer::lexer::MAX_IDENTIFIER_LENGTH),
605    "The maximum length of object identifiers in bytes (PostgreSQL).",
606    true,
607);
608
609pub static WELCOME_MESSAGE: VarDefinition = VarDefinition::new(
610    "welcome_message",
611    value!(bool; true),
612    "Whether to send a notice with a welcome message after a successful connection (Materialize).",
613    true,
614);
615
616/// The logical compaction window for builtin tables and sources that have the
617/// `retained_metrics_relation` flag set.
618///
619/// The existence of this variable is a bit of a hack until we have a fully
620/// general solution for controlling retention windows.
621pub static METRICS_RETENTION: VarDefinition = VarDefinition::new(
622    "metrics_retention",
623    // 30 days
624    value!(Duration; Duration::from_secs(30 * 24 * 60 * 60)),
625    "The time to retain cluster utilization metrics (Materialize).",
626    false,
627);
628
629pub static ALLOWED_CLUSTER_REPLICA_SIZES: VarDefinition = VarDefinition::new(
630    "allowed_cluster_replica_sizes",
631    value!(Vec<Ident>; Vec::new()),
632    "The allowed sizes when creating a new cluster replica (Materialize).",
633    true,
634);
635
636pub static PERSIST_FAST_PATH_LIMIT: VarDefinition = VarDefinition::new(
637    "persist_fast_path_limit",
638    value!(usize; 25),
639    "An exclusive upper bound on the number of results we may return from a Persist fast-path peek; \
640    queries that may return more results will follow the normal / slow path. \
641    Setting this to 0 disables the feature.",
642    false,
643);
644
645/// Controls `mz_adapter::coord::timestamp_oracle::postgres_oracle::DynamicConfig::pg_connection_pool_max_size`.
646pub static PG_TIMESTAMP_ORACLE_CONNECTION_POOL_MAX_SIZE: VarDefinition = VarDefinition::new(
647    "pg_timestamp_oracle_connection_pool_max_size",
648    value!(usize; DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_MAX_SIZE),
649    "Maximum size of the Postgres/CRDB connection pool, used by the Postgres/CRDB timestamp oracle.",
650    false,
651);
652
653/// Controls `mz_adapter::coord::timestamp_oracle::postgres_oracle::DynamicConfig::pg_connection_pool_max_wait`.
654pub static PG_TIMESTAMP_ORACLE_CONNECTION_POOL_MAX_WAIT: VarDefinition = VarDefinition::new(
655    "pg_timestamp_oracle_connection_pool_max_wait",
656    value!(Option<Duration>; Some(DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_MAX_WAIT)),
657    "The maximum time to wait when attempting to obtain a connection from the Postgres/CRDB connection pool, used by the Postgres/CRDB timestamp oracle.",
658    false,
659);
660
661/// Controls `mz_adapter::coord::timestamp_oracle::postgres_oracle::DynamicConfig::pg_connection_pool_ttl`.
662pub static PG_TIMESTAMP_ORACLE_CONNECTION_POOL_TTL: VarDefinition = VarDefinition::new(
663    "pg_timestamp_oracle_connection_pool_ttl",
664    value!(Duration; DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_TTL),
665    "The minimum TTL of a Consensus connection to Postgres/CRDB before it is proactively terminated",
666    false,
667);
668
669/// Controls `mz_adapter::coord::timestamp_oracle::postgres_oracle::DynamicConfig::pg_connection_pool_ttl_stagger`.
670pub static PG_TIMESTAMP_ORACLE_CONNECTION_POOL_TTL_STAGGER: VarDefinition = VarDefinition::new(
671    "pg_timestamp_oracle_connection_pool_ttl_stagger",
672    value!(Duration; DEFAULT_PG_TIMESTAMP_ORACLE_CONNPOOL_TTL_STAGGER),
673    "The minimum time between TTLing Consensus connections to Postgres/CRDB.",
674    false,
675);
676
677/// The default for the `DISK` option when creating managed clusters and cluster replicas.
678pub static DISK_CLUSTER_REPLICAS_DEFAULT: VarDefinition = VarDefinition::new(
679    "disk_cluster_replicas_default",
680    value!(bool; false),
681    "Whether the disk option for managed clusters and cluster replicas should be enabled by default.",
682    false,
683);
684
685pub static UNSAFE_NEW_TRANSACTION_WALL_TIME: VarDefinition = VarDefinition::new(
686    "unsafe_new_transaction_wall_time",
687    value!(Option<CheckedTimestamp<DateTime<Utc>>>; None),
688    "Sets the wall time for all new explicit or implicit transactions to control the value of `now()`. \
689    If not set, uses the system's clock.",
690    // This needs to be true because `user_visible: false` things are only modifiable by the mz_system
691    // and mz_support users, and we want sqllogictest to have access with its user. Because the name
692    // starts with "unsafe" it still won't be visible or changeable by users unless unsafe mode is
693    // enabled.
694    true,
695);
696
697/// Tuning for RocksDB used by `UPSERT` sources that takes effect on restart.
698pub mod upsert_rocksdb {
699    use super::*;
700    use mz_rocksdb_types::config::{CompactionStyle, CompressionType};
701
702    pub static UPSERT_ROCKSDB_COMPACTION_STYLE: VarDefinition = VarDefinition::new(
703        "upsert_rocksdb_compaction_style",
704        value!(CompactionStyle; mz_rocksdb_types::defaults::DEFAULT_COMPACTION_STYLE),
705        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
706        sources. Described in the `mz_rocksdb_types::config` module. \
707        Only takes effect on source restart (Materialize).",
708        false,
709    );
710
711    pub static UPSERT_ROCKSDB_OPTIMIZE_COMPACTION_MEMTABLE_BUDGET: VarDefinition =
712        VarDefinition::new(
713            "upsert_rocksdb_optimize_compaction_memtable_budget",
714            value!(usize; mz_rocksdb_types::defaults::DEFAULT_OPTIMIZE_COMPACTION_MEMTABLE_BUDGET),
715            "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
716        sources. Described in the `mz_rocksdb_types::config` module. \
717        Only takes effect on source restart (Materialize).",
718            false,
719        );
720
721    pub static UPSERT_ROCKSDB_LEVEL_COMPACTION_DYNAMIC_LEVEL_BYTES: VarDefinition =
722        VarDefinition::new(
723            "upsert_rocksdb_level_compaction_dynamic_level_bytes",
724            value!(bool; mz_rocksdb_types::defaults::DEFAULT_LEVEL_COMPACTION_DYNAMIC_LEVEL_BYTES),
725            "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
726        sources. Described in the `mz_rocksdb_types::config` module. \
727        Only takes effect on source restart (Materialize).",
728            false,
729        );
730
731    pub static UPSERT_ROCKSDB_UNIVERSAL_COMPACTION_RATIO: VarDefinition = VarDefinition::new(
732        "upsert_rocksdb_universal_compaction_ratio",
733        value!(i32; mz_rocksdb_types::defaults::DEFAULT_UNIVERSAL_COMPACTION_RATIO),
734        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
735        sources. Described in the `mz_rocksdb_types::config` module. \
736        Only takes effect on source restart (Materialize).",
737        false,
738    );
739
740    pub static UPSERT_ROCKSDB_PARALLELISM: VarDefinition = VarDefinition::new(
741        "upsert_rocksdb_parallelism",
742        value!(Option<i32>; mz_rocksdb_types::defaults::DEFAULT_PARALLELISM),
743        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
744        sources. Described in the `mz_rocksdb_types::config` module. \
745        Only takes effect on source restart (Materialize).",
746        false,
747    );
748
749    pub static UPSERT_ROCKSDB_COMPRESSION_TYPE: VarDefinition = VarDefinition::new(
750        "upsert_rocksdb_compression_type",
751        value!(CompressionType; mz_rocksdb_types::defaults::DEFAULT_COMPRESSION_TYPE),
752        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
753        sources. Described in the `mz_rocksdb_types::config` module. \
754        Only takes effect on source restart (Materialize).",
755        false,
756    );
757
758    pub static UPSERT_ROCKSDB_BOTTOMMOST_COMPRESSION_TYPE: VarDefinition = VarDefinition::new(
759        "upsert_rocksdb_bottommost_compression_type",
760        value!(CompressionType; mz_rocksdb_types::defaults::DEFAULT_BOTTOMMOST_COMPRESSION_TYPE),
761        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
762        sources. Described in the `mz_rocksdb_types::config` module. \
763        Only takes effect on source restart (Materialize).",
764        false,
765    );
766
767    pub static UPSERT_ROCKSDB_BATCH_SIZE: VarDefinition = VarDefinition::new(
768        "upsert_rocksdb_batch_size",
769        value!(usize; mz_rocksdb_types::defaults::DEFAULT_BATCH_SIZE),
770        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
771        sources. Described in the `mz_rocksdb_types::config` module. \
772        Can be changed dynamically (Materialize).",
773        false,
774    );
775
776    pub static UPSERT_ROCKSDB_RETRY_DURATION: VarDefinition = VarDefinition::new(
777        "upsert_rocksdb_retry_duration",
778        value!(Duration; mz_rocksdb_types::defaults::DEFAULT_RETRY_DURATION),
779        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
780        sources. Described in the `mz_rocksdb_types::config` module. \
781        Only takes effect on source restart (Materialize).",
782        false,
783    );
784
785    /// Controls whether automatic spill to disk should be turned on when using `DISK`.
786    pub static UPSERT_ROCKSDB_AUTO_SPILL_TO_DISK: VarDefinition = VarDefinition::new(
787        "upsert_rocksdb_auto_spill_to_disk",
788        value!(bool; true),
789        "Controls whether automatic spill to disk should be turned on when using `DISK`",
790        false,
791    );
792
793    /// The upsert in memory state size threshold after which it will spill to disk.
794    /// The default is 85 MiB = 89128960 bytes
795    pub static UPSERT_ROCKSDB_AUTO_SPILL_THRESHOLD_BYTES: VarDefinition = VarDefinition::new(
796        "upsert_rocksdb_auto_spill_threshold_bytes",
797        value!(usize; mz_rocksdb_types::defaults::DEFAULT_AUTO_SPILL_MEMORY_THRESHOLD),
798        "The upsert in-memory state size threshold in bytes after which it will spill to disk",
799        false,
800    );
801
802    pub static UPSERT_ROCKSDB_STATS_LOG_INTERVAL_SECONDS: VarDefinition = VarDefinition::new(
803        "upsert_rocksdb_stats_log_interval_seconds",
804        value!(u32; mz_rocksdb_types::defaults::DEFAULT_STATS_LOG_INTERVAL_S),
805        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
806        sources. Described in the `mz_rocksdb_types::config` module. \
807        Only takes effect on source restart (Materialize).",
808        false,
809    );
810
811    pub static UPSERT_ROCKSDB_STATS_PERSIST_INTERVAL_SECONDS: VarDefinition = VarDefinition::new(
812        "upsert_rocksdb_stats_persist_interval_seconds",
813        value!(u32; mz_rocksdb_types::defaults::DEFAULT_STATS_PERSIST_INTERVAL_S),
814        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
815        sources. Described in the `mz_rocksdb_types::config` module. \
816        Only takes effect on source restart (Materialize).",
817        false,
818    );
819
820    pub static UPSERT_ROCKSDB_POINT_LOOKUP_BLOCK_CACHE_SIZE_MB: VarDefinition = VarDefinition::new(
821        "upsert_rocksdb_point_lookup_block_cache_size_mb",
822        value!(Option<u32>; None),
823        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
824        sources. Described in the `mz_rocksdb_types::config` module. \
825        Only takes effect on source restart (Materialize).",
826        false,
827    );
828
829    /// The number of times by which allocated buffers will be shrinked in upsert rocksdb.
830    /// If value is 0, then no shrinking will occur.
831    pub static UPSERT_ROCKSDB_SHRINK_ALLOCATED_BUFFERS_BY_RATIO: VarDefinition = VarDefinition::new(
832        "upsert_rocksdb_shrink_allocated_buffers_by_ratio",
833        value!(usize; mz_rocksdb_types::defaults::DEFAULT_SHRINK_BUFFERS_BY_RATIO),
834        "The number of times by which allocated buffers will be shrinked in upsert rocksdb.",
835        false,
836    );
837
838    /// Only used if `upsert_rocksdb_write_buffer_manager_memory_bytes` is also set
839    /// and write buffer manager is enabled
840    pub static UPSERT_ROCKSDB_WRITE_BUFFER_MANAGER_CLUSTER_MEMORY_FRACTION: VarDefinition =
841        VarDefinition::new(
842            "upsert_rocksdb_write_buffer_manager_cluster_memory_fraction",
843            value!(Option<Numeric>; None),
844            "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
845        sources. Described in the `mz_rocksdb_types::config` module. \
846        Only takes effect on source restart (Materialize).",
847            false,
848        );
849
850    /// `upsert_rocksdb_write_buffer_manager_memory_bytes` needs to be set for write buffer manager to be
851    /// used.
852    pub static UPSERT_ROCKSDB_WRITE_BUFFER_MANAGER_MEMORY_BYTES: VarDefinition = VarDefinition::new(
853        "upsert_rocksdb_write_buffer_manager_memory_bytes",
854        value!(Option<usize>; None),
855        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
856        sources. Described in the `mz_rocksdb_types::config` module. \
857        Only takes effect on source restart (Materialize).",
858        false,
859    );
860
861    pub static UPSERT_ROCKSDB_WRITE_BUFFER_MANAGER_ALLOW_STALL: VarDefinition = VarDefinition::new(
862        "upsert_rocksdb_write_buffer_manager_allow_stall",
863        value!(bool; false),
864        "Tuning parameter for RocksDB as used in `UPSERT/DEBEZIUM` \
865        sources. Described in the `mz_rocksdb_types::config` module. \
866        Only takes effect on source restart (Materialize).",
867        false,
868    );
869}
870
871pub static LOGGING_FILTER: VarDefinition = VarDefinition::new_lazy(
872    "log_filter",
873    lazy_value!(CloneableEnvFilter; || CloneableEnvFilter::from_str("info").expect("valid EnvFilter")),
874    "Sets the filter to apply to stderr logging.",
875    false,
876);
877
878pub static OPENTELEMETRY_FILTER: VarDefinition = VarDefinition::new_lazy(
879    "opentelemetry_filter",
880    lazy_value!(CloneableEnvFilter; || CloneableEnvFilter::from_str("info").expect("valid EnvFilter")),
881    "Sets the filter to apply to OpenTelemetry-backed distributed tracing.",
882    false,
883);
884
885pub static LOGGING_FILTER_DEFAULTS: VarDefinition = VarDefinition::new_lazy(
886    "log_filter_defaults",
887    lazy_value!(Vec<SerializableDirective>; || {
888        mz_ore::tracing::LOGGING_DEFAULTS
889            .iter()
890            .map(|d| d.clone().into())
891            .collect()
892    }),
893    "Sets additional default directives to apply to stderr logging. \
894        These apply to all variations of `log_filter`. Directives other than \
895        `module=off` are likely incorrect.",
896    false,
897);
898
899pub static OPENTELEMETRY_FILTER_DEFAULTS: VarDefinition = VarDefinition::new_lazy(
900    "opentelemetry_filter_defaults",
901    lazy_value!(Vec<SerializableDirective>; || {
902        mz_ore::tracing::OPENTELEMETRY_DEFAULTS
903            .iter()
904            .map(|d| d.clone().into())
905            .collect()
906    }),
907    "Sets additional default directives to apply to OpenTelemetry-backed \
908        distributed tracing. \
909        These apply to all variations of `opentelemetry_filter`. Directives other than \
910        `module=off` are likely incorrect.",
911    false,
912);
913
914pub static SENTRY_FILTERS: VarDefinition = VarDefinition::new_lazy(
915    "sentry_filters",
916    lazy_value!(Vec<SerializableDirective>; || {
917        mz_ore::tracing::SENTRY_DEFAULTS
918            .iter()
919            .map(|d| d.clone().into())
920            .collect()
921    }),
922    "Sets additional default directives to apply to sentry logging. \
923        These apply on top of a default `info` directive. Directives other than \
924        `module=off` are likely incorrect.",
925    false,
926);
927
928pub static WEBHOOKS_SECRETS_CACHING_TTL_SECS: VarDefinition = VarDefinition::new_lazy(
929    "webhooks_secrets_caching_ttl_secs",
930    lazy_value!(usize; || {
931        usize::cast_from(mz_secrets::cache::DEFAULT_TTL_SECS)
932    }),
933    "Sets the time-to-live for values in the Webhooks secrets cache.",
934    false,
935);
936
937pub static COORD_SLOW_MESSAGE_WARN_THRESHOLD: VarDefinition = VarDefinition::new(
938    "coord_slow_message_warn_threshold",
939    value!(Duration; Duration::from_secs(30)),
940    "Sets the threshold at which we will error! for a coordinator message being slow.",
941    false,
942);
943
944/// Controls the connect_timeout setting when connecting to PG via `mz_postgres_util`.
945pub static PG_SOURCE_CONNECT_TIMEOUT: VarDefinition = VarDefinition::new(
946    "pg_source_connect_timeout",
947    value!(Duration; DEFAULT_PG_SOURCE_CONNECT_TIMEOUT),
948    "Sets the timeout applied to socket-level connection attempts for PG \
949    replication connections (Materialize).",
950    false,
951);
952
953/// Sets the maximum number of TCP keepalive probes that will be sent before dropping a connection
954/// when connecting to PG via `mz_postgres_util`.
955pub static PG_SOURCE_TCP_KEEPALIVES_RETRIES: VarDefinition = VarDefinition::new(
956    "pg_source_tcp_keepalives_retries",
957    value!(u32; DEFAULT_PG_SOURCE_TCP_KEEPALIVES_RETRIES),
958    "Sets the maximum number of TCP keepalive probes that will be sent before dropping \
959    a connection when connecting to PG via `mz_postgres_util` (Materialize).",
960    false,
961);
962
963/// Sets the amount of idle time before a keepalive packet is sent on the connection when connecting
964/// to PG via `mz_postgres_util`.
965pub static PG_SOURCE_TCP_KEEPALIVES_IDLE: VarDefinition = VarDefinition::new(
966    "pg_source_tcp_keepalives_idle",
967    value!(Duration; DEFAULT_PG_SOURCE_TCP_KEEPALIVES_IDLE),
968    "Sets the amount of idle time before a keepalive packet is sent on the connection \
969        when connecting to PG via `mz_postgres_util` (Materialize).",
970    false,
971);
972
973/// Sets the time interval between TCP keepalive probes when connecting to PG via `mz_postgres_util`.
974pub static PG_SOURCE_TCP_KEEPALIVES_INTERVAL: VarDefinition = VarDefinition::new(
975    "pg_source_tcp_keepalives_interval",
976    value!(Duration; DEFAULT_PG_SOURCE_TCP_KEEPALIVES_INTERVAL),
977    "Sets the time interval between TCP keepalive probes when connecting to PG via \
978        replication (Materialize).",
979    false,
980);
981
982/// Sets the TCP user timeout when connecting to PG via `mz_postgres_util`.
983pub static PG_SOURCE_TCP_USER_TIMEOUT: VarDefinition = VarDefinition::new(
984    "pg_source_tcp_user_timeout",
985    value!(Duration; DEFAULT_PG_SOURCE_TCP_USER_TIMEOUT),
986    "Sets the TCP user timeout when connecting to PG via `mz_postgres_util` (Materialize).",
987    false,
988);
989
990/// Sets whether to apply the TCP configuration parameters on the server when
991/// connecting to PG via `mz_postgres_util`.
992pub static PG_SOURCE_TCP_CONFIGURE_SERVER: VarDefinition = VarDefinition::new(
993    "pg_source_tcp_configure_server",
994    value!(bool; DEFAULT_PG_SOURCE_TCP_CONFIGURE_SERVER),
995    "Sets whether to apply the TCP configuration parameters on the server when connecting to PG via `mz_postgres_util` (Materialize).",
996    false,
997);
998
999/// Sets the `statement_timeout` value to use during the snapshotting phase of
1000/// PG sources.
1001pub static PG_SOURCE_SNAPSHOT_STATEMENT_TIMEOUT: VarDefinition = VarDefinition::new(
1002    "pg_source_snapshot_statement_timeout",
1003    value!(Duration; mz_postgres_util::DEFAULT_SNAPSHOT_STATEMENT_TIMEOUT),
1004    "Sets the `statement_timeout` value to use during the snapshotting phase of PG sources (Materialize)",
1005    false,
1006);
1007
1008/// Sets the `wal_sender_timeout` value to use during the replication phase of
1009/// PG sources.
1010pub static PG_SOURCE_WAL_SENDER_TIMEOUT: VarDefinition = VarDefinition::new(
1011    "pg_source_wal_sender_timeout",
1012    value!(Option<Duration>; DEFAULT_PG_SOURCE_WAL_SENDER_TIMEOUT),
1013    "Sets the `wal_sender_timeout` value to use during the replication phase of PG sources (Materialize)",
1014    false,
1015);
1016
1017/// Please see `PgSourceSnapshotConfig`.
1018pub static PG_SOURCE_SNAPSHOT_COLLECT_STRICT_COUNT: VarDefinition = VarDefinition::new(
1019    "pg_source_snapshot_collect_strict_count",
1020    value!(bool; mz_storage_types::parameters::PgSourceSnapshotConfig::new().collect_strict_count),
1021    "Please see <https://dev.materialize.com/api/rust-private\
1022        /mz_storage_types/parameters\
1023        /struct.PgSourceSnapshotConfig.html#structfield.collect_strict_count>",
1024    false,
1025);
1026
1027/// Please see `PgSourceSnapshotConfig`.
1028pub static PG_SOURCE_SNAPSHOT_FALLBACK_TO_STRICT_COUNT: VarDefinition = VarDefinition::new(
1029    "pg_source_snapshot_fallback_to_strict_count",
1030    value!(bool; mz_storage_types::parameters::PgSourceSnapshotConfig::new().fallback_to_strict_count),
1031    "Please see <https://dev.materialize.com/api/rust-private\
1032        /mz_storage_types/parameters\
1033        /struct.PgSourceSnapshotConfig.html#structfield.fallback_to_strict_count>",
1034    false,
1035);
1036
1037/// Please see `PgSourceSnapshotConfig`.
1038pub static PG_SOURCE_SNAPSHOT_WAIT_FOR_COUNT: VarDefinition = VarDefinition::new(
1039    "pg_source_snapshot_wait_for_count",
1040    value!(bool; mz_storage_types::parameters::PgSourceSnapshotConfig::new().wait_for_count),
1041    "Please see <https://dev.materialize.com/api/rust-private\
1042        /mz_storage_types/parameters\
1043        /struct.PgSourceSnapshotConfig.html#structfield.wait_for_count>",
1044    false,
1045);
1046
1047/// Sets the time between TCP keepalive probes when connecting to MySQL via `mz_mysql_util`.
1048pub static MYSQL_SOURCE_TCP_KEEPALIVE: VarDefinition = VarDefinition::new(
1049    "mysql_source_tcp_keepalive",
1050    value!(Duration; mz_mysql_util::DEFAULT_TCP_KEEPALIVE),
1051    "Sets the time between TCP keepalive probes when connecting to MySQL",
1052    false,
1053);
1054
1055/// Sets the `max_execution_time` value to use during the snapshotting phase of
1056/// MySQL sources.
1057pub static MYSQL_SOURCE_SNAPSHOT_MAX_EXECUTION_TIME: VarDefinition = VarDefinition::new(
1058    "mysql_source_snapshot_max_execution_time",
1059    value!(Duration; mz_mysql_util::DEFAULT_SNAPSHOT_MAX_EXECUTION_TIME),
1060    "Sets the `max_execution_time` value to use during the snapshotting phase of MySQL sources (Materialize)",
1061    false,
1062);
1063
1064/// Sets the `lock_wait_timeout` value to use during the snapshotting phase of
1065/// MySQL sources.
1066pub static MYSQL_SOURCE_SNAPSHOT_LOCK_WAIT_TIMEOUT: VarDefinition = VarDefinition::new(
1067    "mysql_source_snapshot_lock_wait_timeout",
1068    value!(Duration; mz_mysql_util::DEFAULT_SNAPSHOT_LOCK_WAIT_TIMEOUT),
1069    "Sets the `lock_wait_timeout` value to use during the snapshotting phase of MySQL sources (Materialize)",
1070    false,
1071);
1072
1073/// Sets the timeout for establishing an authenticated connection to MySQL
1074pub static MYSQL_SOURCE_CONNECT_TIMEOUT: VarDefinition = VarDefinition::new(
1075    "mysql_source_connect_timeout",
1076    value!(Duration; mz_mysql_util::DEFAULT_CONNECT_TIMEOUT),
1077    "Sets the timeout for establishing an authenticated connection to MySQL",
1078    false,
1079);
1080
1081/// Controls the check interval for connections to SSH bastions via `mz_ssh_util`.
1082pub static SSH_CHECK_INTERVAL: VarDefinition = VarDefinition::new(
1083    "ssh_check_interval",
1084    value!(Duration; mz_ssh_util::tunnel::DEFAULT_CHECK_INTERVAL),
1085    "Controls the check interval for connections to SSH bastions via `mz_ssh_util`.",
1086    false,
1087);
1088
1089/// Controls the connect timeout for connections to SSH bastions via `mz_ssh_util`.
1090pub static SSH_CONNECT_TIMEOUT: VarDefinition = VarDefinition::new(
1091    "ssh_connect_timeout",
1092    value!(Duration; mz_ssh_util::tunnel::DEFAULT_CONNECT_TIMEOUT),
1093    "Controls the connect timeout for connections to SSH bastions via `mz_ssh_util`.",
1094    false,
1095);
1096
1097/// Controls the keepalive idle interval for connections to SSH bastions via `mz_ssh_util`.
1098pub static SSH_KEEPALIVES_IDLE: VarDefinition = VarDefinition::new(
1099    "ssh_keepalives_idle",
1100    value!(Duration; mz_ssh_util::tunnel::DEFAULT_KEEPALIVES_IDLE),
1101    "Controls the keepalive idle interval for connections to SSH bastions via `mz_ssh_util`.",
1102    false,
1103);
1104
1105/// Enables `socket.keepalive.enable` for rdkafka client connections. Defaults to true.
1106pub static KAFKA_SOCKET_KEEPALIVE: VarDefinition = VarDefinition::new(
1107    "kafka_socket_keepalive",
1108    value!(bool; mz_kafka_util::client::DEFAULT_KEEPALIVE),
1109    "Enables `socket.keepalive.enable` for rdkafka client connections. Defaults to true.",
1110    false,
1111);
1112
1113/// Controls `socket.timeout.ms` for rdkafka client connections. Defaults to the rdkafka default
1114/// (60000ms). Cannot be greater than 300000ms, more than 100ms greater than
1115/// `kafka_transaction_timeout`, or less than 10ms.
1116pub static KAFKA_SOCKET_TIMEOUT: VarDefinition = VarDefinition::new(
1117    "kafka_socket_timeout",
1118    value!(Option<Duration>; None),
1119    "Controls `socket.timeout.ms` for rdkafka \
1120        client connections. Defaults to the rdkafka default (60000ms) or \
1121        the set transaction timeout + 100ms, whichever one is smaller. \
1122        Cannot be greater than 300000ms, more than 100ms greater than \
1123        `kafka_transaction_timeout`, or less than 10ms.",
1124    false,
1125);
1126
1127/// Controls `transaction.timeout.ms` for rdkafka client connections. Defaults to the rdkafka default
1128/// (60000ms). Cannot be greater than `i32::MAX` or less than 1000ms.
1129pub static KAFKA_TRANSACTION_TIMEOUT: VarDefinition = VarDefinition::new(
1130    "kafka_transaction_timeout",
1131    value!(Duration; mz_kafka_util::client::DEFAULT_TRANSACTION_TIMEOUT),
1132    "Controls `transaction.timeout.ms` for rdkafka \
1133        client connections. Defaults to the 10min. \
1134        Cannot be greater than `i32::MAX` or less than 1000ms.",
1135    false,
1136);
1137
1138/// Controls `socket.connection.setup.timeout.ms` for rdkafka client connections. Defaults to the rdkafka default
1139/// (30000ms). Cannot be greater than `i32::MAX` or less than 1000ms
1140pub static KAFKA_SOCKET_CONNECTION_SETUP_TIMEOUT: VarDefinition = VarDefinition::new(
1141    "kafka_socket_connection_setup_timeout",
1142    value!(Duration; mz_kafka_util::client::DEFAULT_SOCKET_CONNECTION_SETUP_TIMEOUT),
1143    "Controls `socket.connection.setup.timeout.ms` for rdkafka \
1144        client connections. Defaults to the rdkafka default (30000ms). \
1145        Cannot be greater than `i32::MAX` or less than 1000ms",
1146    false,
1147);
1148
1149/// Controls the timeout when fetching kafka metadata. Defaults to 10s.
1150pub static KAFKA_FETCH_METADATA_TIMEOUT: VarDefinition = VarDefinition::new(
1151    "kafka_fetch_metadata_timeout",
1152    value!(Duration; mz_kafka_util::client::DEFAULT_FETCH_METADATA_TIMEOUT),
1153    "Controls the timeout when fetching kafka metadata. \
1154        Defaults to 10s.",
1155    false,
1156);
1157
1158/// Controls the timeout when fetching kafka progress records. Defaults to 60s.
1159pub static KAFKA_PROGRESS_RECORD_FETCH_TIMEOUT: VarDefinition = VarDefinition::new(
1160    "kafka_progress_record_fetch_timeout",
1161    value!(Option<Duration>; None),
1162    "Controls the timeout when fetching kafka progress records. \
1163        Defaults to 60s or the transaction timeout, whichever one is larger.",
1164    false,
1165);
1166
1167/// The maximum number of in-flight bytes emitted by persist_sources feeding _storage
1168/// dataflows_.
1169/// Currently defaults to 256MiB = 268435456 bytes
1170/// Note: Backpressure will only be turned on if disk is enabled based on
1171/// `storage_dataflow_max_inflight_bytes_disk_only` flag
1172pub static STORAGE_DATAFLOW_MAX_INFLIGHT_BYTES: VarDefinition = VarDefinition::new(
1173    "storage_dataflow_max_inflight_bytes",
1174    value!(Option<usize>; Some(256 * 1024 * 1024)),
1175    "The maximum number of in-flight bytes emitted by persist_sources feeding \
1176        storage dataflows. Defaults to backpressure enabled (Materialize).",
1177    false,
1178);
1179
1180/// Configuration ratio to shrink unusef buffers in upsert by.
1181/// For eg: is 2 is set, then the buffers will be reduced by 2 i.e. halved.
1182/// Default is 0, which means shrinking is disabled.
1183pub static STORAGE_SHRINK_UPSERT_UNUSED_BUFFERS_BY_RATIO: VarDefinition = VarDefinition::new(
1184    "storage_shrink_upsert_unused_buffers_by_ratio",
1185    value!(usize; 0),
1186    "Configuration ratio to shrink unusef buffers in upsert by",
1187    false,
1188);
1189
1190/// The fraction of the cluster replica size to be used as the maximum number of
1191/// in-flight bytes emitted by persist_sources feeding storage dataflows.
1192/// If not configured, the storage_dataflow_max_inflight_bytes value will be used.
1193/// For this value to be used storage_dataflow_max_inflight_bytes needs to be set.
1194pub static STORAGE_DATAFLOW_MAX_INFLIGHT_BYTES_TO_CLUSTER_SIZE_FRACTION: VarDefinition =
1195    VarDefinition::new_lazy(
1196        "storage_dataflow_max_inflight_bytes_to_cluster_size_fraction",
1197        lazy_value!(Option<Numeric>; || Some(0.0025.into())),
1198        "The fraction of the cluster replica size to be used as the maximum number of \
1199            in-flight bytes emitted by persist_sources feeding storage dataflows. \
1200            If not configured, the storage_dataflow_max_inflight_bytes value will be used.",
1201        false,
1202    );
1203
1204pub static STORAGE_DATAFLOW_MAX_INFLIGHT_BYTES_DISK_ONLY: VarDefinition = VarDefinition::new(
1205    "storage_dataflow_max_inflight_bytes_disk_only",
1206    value!(bool; true),
1207    "Whether or not `storage_dataflow_max_inflight_bytes` applies only to \
1208        upsert dataflows using disks. Defaults to true (Materialize).",
1209    false,
1210);
1211
1212/// The interval to submit statistics to `mz_source_statistics_per_worker` and `mz_sink_statistics_per_worker`.
1213pub static STORAGE_STATISTICS_INTERVAL: VarDefinition = VarDefinition::new(
1214    "storage_statistics_interval",
1215    value!(Duration; mz_storage_types::parameters::STATISTICS_INTERVAL_DEFAULT),
1216    "The interval to submit statistics to `mz_source_statistics_per_worker` \
1217        and `mz_sink_statistics` (Materialize).",
1218    false,
1219);
1220
1221/// The interval to collect statistics for `mz_source_statistics_per_worker` and `mz_sink_statistics_per_worker` in
1222/// clusterd. Controls the accuracy of metrics.
1223pub static STORAGE_STATISTICS_COLLECTION_INTERVAL: VarDefinition = VarDefinition::new(
1224    "storage_statistics_collection_interval",
1225    value!(Duration; mz_storage_types::parameters::STATISTICS_COLLECTION_INTERVAL_DEFAULT),
1226    "The interval to collect statistics for `mz_source_statistics_per_worker` \
1227        and `mz_sink_statistics_per_worker` in clusterd. Controls the accuracy of metrics \
1228        (Materialize).",
1229    false,
1230);
1231
1232pub static STORAGE_RECORD_SOURCE_SINK_NAMESPACED_ERRORS: VarDefinition = VarDefinition::new(
1233    "storage_record_source_sink_namespaced_errors",
1234    value!(bool; true),
1235    "Whether or not to record namespaced errors in the status history tables",
1236    false,
1237);
1238
1239/// Boolean flag indicating whether to enable syncing from
1240/// LaunchDarkly. Can be turned off as an emergency measure to still
1241/// be able to alter parameters while LD is broken.
1242pub static ENABLE_LAUNCHDARKLY: VarDefinition = VarDefinition::new(
1243    "enable_launchdarkly",
1244    value!(bool; true),
1245    "Boolean flag indicating whether flag synchronization from LaunchDarkly should be enabled (Materialize).",
1246    false,
1247);
1248
1249/// Feature flag indicating whether real time recency is enabled. Not that
1250/// unlike other feature flags, this is made available at the session level, so
1251/// is additionally gated by a feature flag.
1252pub static REAL_TIME_RECENCY: VarDefinition = VarDefinition::new(
1253    "real_time_recency",
1254    value!(bool; false),
1255    "Feature flag indicating whether real time recency is enabled (Materialize).",
1256    true,
1257)
1258.with_feature_flag(&ALLOW_REAL_TIME_RECENCY);
1259
1260pub static REAL_TIME_RECENCY_TIMEOUT: VarDefinition = VarDefinition::new(
1261    "real_time_recency_timeout",
1262    value!(Duration; Duration::from_secs(10)),
1263    "Sets the maximum allowed duration of SELECTs that actively use real-time \
1264    recency, i.e. reach out to an external system to determine their most recencly exposed \
1265    data (Materialize).",
1266    true,
1267)
1268.with_feature_flag(&ALLOW_REAL_TIME_RECENCY);
1269
1270pub static EMIT_PLAN_INSIGHTS_NOTICE: VarDefinition = VarDefinition::new(
1271    "emit_plan_insights_notice",
1272    value!(bool; false),
1273    "Boolean flag indicating whether to send a NOTICE with JSON-formatted plan insights before executing a SELECT statement (Materialize).",
1274    true,
1275);
1276
1277pub static EMIT_TIMESTAMP_NOTICE: VarDefinition = VarDefinition::new(
1278    "emit_timestamp_notice",
1279    value!(bool; false),
1280    "Boolean flag indicating whether to send a NOTICE with timestamp explanations of queries (Materialize).",
1281    true,
1282);
1283
1284pub static EMIT_TRACE_ID_NOTICE: VarDefinition = VarDefinition::new(
1285    "emit_trace_id_notice",
1286    value!(bool; false),
1287    "Boolean flag indicating whether to send a NOTICE specifying the trace id when available (Materialize).",
1288    true,
1289);
1290
1291pub static UNSAFE_MOCK_AUDIT_EVENT_TIMESTAMP: VarDefinition = VarDefinition::new(
1292    "unsafe_mock_audit_event_timestamp",
1293    value!(Option<mz_repr::Timestamp>; None),
1294    "Mocked timestamp to use for audit events for testing purposes",
1295    false,
1296);
1297
1298pub static ENABLE_RBAC_CHECKS: VarDefinition = VarDefinition::new(
1299    "enable_rbac_checks",
1300    value!(bool; true),
1301    "User facing global boolean flag indicating whether to apply RBAC checks before \
1302        executing statements (Materialize).",
1303    true,
1304);
1305
1306pub static ENABLE_SESSION_RBAC_CHECKS: VarDefinition = VarDefinition::new(
1307    "enable_session_rbac_checks",
1308    // TODO(jkosh44) Once RBAC is enabled in all environments, change this to `true`.
1309    value!(bool; false),
1310    "User facing session boolean flag indicating whether to apply RBAC checks before \
1311        executing statements (Materialize).",
1312    true,
1313);
1314
1315pub static EMIT_INTROSPECTION_QUERY_NOTICE: VarDefinition = VarDefinition::new(
1316    "emit_introspection_query_notice",
1317    value!(bool; true),
1318    "Whether to print a notice when querying per-replica introspection sources.",
1319    true,
1320);
1321
1322// TODO(mgree) change this to a SelectOption
1323pub static ENABLE_SESSION_CARDINALITY_ESTIMATES: VarDefinition = VarDefinition::new(
1324    "enable_session_cardinality_estimates",
1325    value!(bool; false),
1326    "Feature flag indicating whether to use cardinality estimates when optimizing queries; \
1327        does not affect EXPLAIN WITH(cardinality) (Materialize).",
1328    true,
1329)
1330.with_feature_flag(&ENABLE_CARDINALITY_ESTIMATES);
1331
1332pub static OPTIMIZER_STATS_TIMEOUT: VarDefinition = VarDefinition::new(
1333    "optimizer_stats_timeout",
1334    value!(Duration; Duration::from_millis(250)),
1335    "Sets the timeout applied to the optimizer's statistics collection from storage; \
1336        applied to non-oneshot, i.e., long-lasting queries, like CREATE MATERIALIZED VIEW (Materialize).",
1337    false,
1338);
1339
1340pub static OPTIMIZER_ONESHOT_STATS_TIMEOUT: VarDefinition = VarDefinition::new(
1341    "optimizer_oneshot_stats_timeout",
1342    value!(Duration; Duration::from_millis(10)),
1343    "Sets the timeout applied to the optimizer's statistics collection from storage; \
1344        applied to oneshot queries, like SELECT (Materialize).",
1345    false,
1346);
1347
1348pub static PRIVATELINK_STATUS_UPDATE_QUOTA_PER_MINUTE: VarDefinition = VarDefinition::new(
1349    "privatelink_status_update_quota_per_minute",
1350    value!(u32; 20),
1351    "Sets the per-minute quota for privatelink vpc status updates to be written to \
1352        the storage-collection-backed system table. This value implies the total and burst quota per-minute.",
1353    false,
1354);
1355
1356pub static STATEMENT_LOGGING_SAMPLE_RATE: VarDefinition = VarDefinition::new_lazy(
1357    "statement_logging_sample_rate",
1358    lazy_value!(Numeric; || 0.1.into()),
1359    "User-facing session variable indicating how many statement executions should be \
1360        logged, subject to constraint by the system variable `statement_logging_max_sample_rate` (Materialize).",
1361    true,
1362).with_constraint(&NUMERIC_BOUNDED_0_1_INCLUSIVE);
1363
1364pub static ARRANGEMENT_EXERT_PROPORTIONALITY: VarDefinition = VarDefinition::new(
1365    "arrangement_exert_proportionality",
1366    value!(u32; 16),
1367    "Value that controls how much merge effort to exert on arrangements.",
1368    false,
1369);
1370
1371pub static ENABLE_DEFAULT_CONNECTION_VALIDATION: VarDefinition = VarDefinition::new(
1372    "enable_default_connection_validation",
1373    value!(bool; true),
1374    "LD facing global boolean flag that allows turning default connection validation off for everyone (Materialize).",
1375    false,
1376);
1377
1378pub static STATEMENT_LOGGING_MAX_DATA_CREDIT: VarDefinition = VarDefinition::new(
1379    "statement_logging_max_data_credit",
1380    value!(Option<usize>; None),
1381    // The idea is that during periods of low logging, tokens can accumulate up to this value,
1382    // and then be depleted during periods of high logging.
1383    "The maximum number of bytes that can be logged for statement logging in short burts, or NULL if unlimited (Materialize).",
1384    false,
1385);
1386
1387pub static STATEMENT_LOGGING_TARGET_DATA_RATE: VarDefinition = VarDefinition::new(
1388    "statement_logging_target_data_rate",
1389    value!(Option<usize>; None),
1390    "The maximum sustained data rate of statement logging, in bytes per second, or NULL if unlimited (Materialize).",
1391    false,
1392);
1393
1394pub static STATEMENT_LOGGING_MAX_SAMPLE_RATE: VarDefinition = VarDefinition::new_lazy(
1395    "statement_logging_max_sample_rate",
1396    lazy_value!(Numeric; || 0.99.into()),
1397    "The maximum rate at which statements may be logged. If this value is less than \
1398        that of `statement_logging_sample_rate`, the latter is ignored (Materialize).",
1399    true,
1400)
1401.with_constraint(&NUMERIC_BOUNDED_0_1_INCLUSIVE);
1402
1403pub static STATEMENT_LOGGING_DEFAULT_SAMPLE_RATE: VarDefinition = VarDefinition::new_lazy(
1404    "statement_logging_default_sample_rate",
1405    lazy_value!(Numeric; || 0.99.into()),
1406    "The default value of `statement_logging_sample_rate` for new sessions (Materialize).",
1407    true,
1408)
1409.with_constraint(&NUMERIC_BOUNDED_0_1_INCLUSIVE);
1410
1411pub static ENABLE_INTERNAL_STATEMENT_LOGGING: VarDefinition = VarDefinition::new(
1412    "enable_internal_statement_logging",
1413    value!(bool; false),
1414    "Whether to log statements from the `mz_system` user.",
1415    false,
1416);
1417
1418pub static AUTO_ROUTE_CATALOG_QUERIES: VarDefinition = VarDefinition::new(
1419    "auto_route_catalog_queries",
1420    value!(bool; true),
1421    "Whether to force queries that depend only on system tables, to run on the mz_catalog_server cluster (Materialize).",
1422    true,
1423);
1424
1425pub static MAX_CONNECTIONS: VarDefinition = VarDefinition::new(
1426    "max_connections",
1427    value!(u32; 5000),
1428    "The maximum number of concurrent connections (PostgreSQL).",
1429    true,
1430);
1431
1432pub static SUPERUSER_RESERVED_CONNECTIONS: VarDefinition = VarDefinition::new(
1433    "superuser_reserved_connections",
1434    value!(u32; 3),
1435    "The number of connections that are reserved for superusers (PostgreSQL).",
1436    true,
1437);
1438
1439/// Controls [`mz_storage_types::parameters::StorageParameters::keep_n_source_status_history_entries`].
1440pub static KEEP_N_SOURCE_STATUS_HISTORY_ENTRIES: VarDefinition = VarDefinition::new(
1441    "keep_n_source_status_history_entries",
1442    value!(usize; 5),
1443    "On reboot, truncate all but the last n entries per ID in the source_status_history collection (Materialize).",
1444    false,
1445);
1446
1447/// Controls [`mz_storage_types::parameters::StorageParameters::keep_n_sink_status_history_entries`].
1448pub static KEEP_N_SINK_STATUS_HISTORY_ENTRIES: VarDefinition = VarDefinition::new(
1449    "keep_n_sink_status_history_entries",
1450    value!(usize; 5),
1451    "On reboot, truncate all but the last n entries per ID in the sink_status_history collection (Materialize).",
1452    false,
1453);
1454
1455/// Controls [`mz_storage_types::parameters::StorageParameters::keep_n_privatelink_status_history_entries`].
1456pub static KEEP_N_PRIVATELINK_STATUS_HISTORY_ENTRIES: VarDefinition = VarDefinition::new(
1457    "keep_n_privatelink_status_history_entries",
1458    value!(usize; 5),
1459    "On reboot, truncate all but the last n entries per ID in the mz_aws_privatelink_connection_status_history \
1460        collection (Materialize).",
1461    false,
1462);
1463
1464/// Controls [`mz_storage_types::parameters::StorageParameters::replica_status_history_retention_window`].
1465pub static REPLICA_STATUS_HISTORY_RETENTION_WINDOW: VarDefinition = VarDefinition::new(
1466    "replica_status_history_retention_window",
1467    value!(Duration; REPLICA_STATUS_HISTORY_RETENTION_WINDOW_DEFAULT),
1468    "On reboot, truncate up all entries past the retention window in the mz_cluster_replica_status_history \
1469        collection (Materialize).",
1470    false,
1471);
1472
1473pub static ENABLE_STORAGE_SHARD_FINALIZATION: VarDefinition = VarDefinition::new(
1474    "enable_storage_shard_finalization",
1475    value!(bool; true),
1476    "Whether to allow the storage client to finalize shards (Materialize).",
1477    false,
1478);
1479
1480pub static ENABLE_CONSOLIDATE_AFTER_UNION_NEGATE: VarDefinition = VarDefinition::new(
1481    "enable_consolidate_after_union_negate",
1482    value!(bool; true),
1483    "consolidation after Unions that have a Negated input (Materialize).",
1484    true,
1485);
1486
1487pub static ENABLE_REDUCE_REDUCTION: VarDefinition = VarDefinition::new(
1488    "enable_reduce_reduction",
1489    value!(bool; true),
1490    "split complex reductions in to simpler ones and a join (Materialize).",
1491    true,
1492);
1493
1494pub static MIN_TIMESTAMP_INTERVAL: VarDefinition = VarDefinition::new(
1495    "min_timestamp_interval",
1496    value!(Duration; Duration::from_millis(1000)),
1497    "Minimum timestamp interval",
1498    false,
1499);
1500
1501pub static MAX_TIMESTAMP_INTERVAL: VarDefinition = VarDefinition::new(
1502    "max_timestamp_interval",
1503    value!(Duration; Duration::from_millis(1000)),
1504    "Maximum timestamp interval",
1505    false,
1506);
1507
1508pub static WEBHOOK_CONCURRENT_REQUEST_LIMIT: VarDefinition = VarDefinition::new(
1509    "webhook_concurrent_request_limit",
1510    value!(usize; WEBHOOK_CONCURRENCY_LIMIT),
1511    "Maximum number of concurrent requests for appending to a webhook source.",
1512    false,
1513);
1514
1515pub static USER_STORAGE_MANAGED_COLLECTIONS_BATCH_DURATION: VarDefinition = VarDefinition::new(
1516    "user_storage_managed_collections_batch_duration",
1517    value!(Duration; STORAGE_MANAGED_COLLECTIONS_BATCH_DURATION_DEFAULT),
1518    "Duration which we'll wait to collect a batch of events for a webhook source.",
1519    false,
1520);
1521
1522// This system var will need to point to the name of an existing network policy
1523// this will be enforced on alter_system_set
1524pub static NETWORK_POLICY: VarDefinition = VarDefinition::new_lazy(
1525    "network_policy",
1526    lazy_value!(String; || "default".to_string()),
1527    "Sets the fallback network policy applied to all users without an explicit policy.",
1528    true,
1529);
1530
1531pub static FORCE_SOURCE_TABLE_SYNTAX: VarDefinition = VarDefinition::new(
1532    "force_source_table_syntax",
1533    value!(bool; false),
1534    "Force use of new source model (CREATE TABLE .. FROM SOURCE) and migrate existing sources",
1535    true,
1536);
1537
1538pub static OPTIMIZER_E2E_LATENCY_WARNING_THRESHOLD: VarDefinition = VarDefinition::new(
1539    "optimizer_e2e_latency_warning_threshold",
1540    value!(Duration; Duration::from_millis(500)),
1541    "Sets the duration that a query can take to compile; queries that take longer \
1542        will trigger a warning. If this value is specified without units, it is taken as \
1543        milliseconds. A value of zero disables the timeout (Materialize).",
1544    true,
1545);
1546
1547/// Configuration for gRPC client connections.
1548pub mod grpc_client {
1549    use super::*;
1550
1551    pub static CONNECT_TIMEOUT: VarDefinition = VarDefinition::new(
1552        "grpc_client_connect_timeout",
1553        value!(Duration; Duration::from_secs(5)),
1554        "Timeout to apply to initial gRPC client connection establishment.",
1555        false,
1556    );
1557
1558    pub static HTTP2_KEEP_ALIVE_INTERVAL: VarDefinition = VarDefinition::new(
1559        "grpc_client_http2_keep_alive_interval",
1560        value!(Duration; Duration::from_secs(3)),
1561        "Idle time to wait before sending HTTP/2 PINGs to maintain established gRPC client connections.",
1562        false,
1563    );
1564
1565    pub static HTTP2_KEEP_ALIVE_TIMEOUT: VarDefinition = VarDefinition::new(
1566        "grpc_client_http2_keep_alive_timeout",
1567        value!(Duration; Duration::from_secs(5)),
1568        "Time to wait for HTTP/2 pong response before terminating a gRPC client connection.",
1569        false,
1570    );
1571}
1572
1573/// Configuration for how cluster replicas are scheduled.
1574pub mod cluster_scheduling {
1575    use super::*;
1576    use mz_orchestrator::scheduling_config::*;
1577
1578    pub static CLUSTER_MULTI_PROCESS_REPLICA_AZ_AFFINITY_WEIGHT: VarDefinition = VarDefinition::new(
1579        "cluster_multi_process_replica_az_affinity_weight",
1580        value!(Option<i32>; DEFAULT_POD_AZ_AFFINITY_WEIGHT),
1581        "Whether or not to add an availability zone affinity between instances of \
1582            multi-process replicas. Either an affinity weight or empty (off) (Materialize).",
1583        false,
1584    );
1585
1586    pub static CLUSTER_SOFTEN_REPLICATION_ANTI_AFFINITY: VarDefinition = VarDefinition::new(
1587        "cluster_soften_replication_anti_affinity",
1588        value!(bool; DEFAULT_SOFTEN_REPLICATION_ANTI_AFFINITY),
1589        "Whether or not to turn the node-scope anti affinity between replicas \
1590            in the same cluster into a preference (Materialize).",
1591        false,
1592    );
1593
1594    pub static CLUSTER_SOFTEN_REPLICATION_ANTI_AFFINITY_WEIGHT: VarDefinition = VarDefinition::new(
1595        "cluster_soften_replication_anti_affinity_weight",
1596        value!(i32; DEFAULT_SOFTEN_REPLICATION_ANTI_AFFINITY_WEIGHT),
1597        "The preference weight for `cluster_soften_replication_anti_affinity` (Materialize).",
1598        false,
1599    );
1600
1601    pub static CLUSTER_ENABLE_TOPOLOGY_SPREAD: VarDefinition = VarDefinition::new(
1602        "cluster_enable_topology_spread",
1603        value!(bool; DEFAULT_TOPOLOGY_SPREAD_ENABLED),
1604        "Whether or not to add topology spread constraints among replicas in the same cluster (Materialize).",
1605        false,
1606    );
1607
1608    pub static CLUSTER_TOPOLOGY_SPREAD_IGNORE_NON_SINGULAR_SCALE: VarDefinition =
1609        VarDefinition::new(
1610            "cluster_topology_spread_ignore_non_singular_scale",
1611            value!(bool; DEFAULT_TOPOLOGY_SPREAD_IGNORE_NON_SINGULAR_SCALE),
1612            "If true, ignore replicas with more than 1 process when adding topology spread constraints (Materialize).",
1613            false,
1614        );
1615
1616    pub static CLUSTER_TOPOLOGY_SPREAD_MAX_SKEW: VarDefinition = VarDefinition::new(
1617        "cluster_topology_spread_max_skew",
1618        value!(i32; DEFAULT_TOPOLOGY_SPREAD_MAX_SKEW),
1619        "The `maxSkew` for replica topology spread constraints (Materialize).",
1620        false,
1621    );
1622
1623    pub static CLUSTER_TOPOLOGY_SPREAD_SOFT: VarDefinition = VarDefinition::new(
1624        "cluster_topology_spread_soft",
1625        value!(bool; DEFAULT_TOPOLOGY_SPREAD_SOFT),
1626        "If true, soften the topology spread constraints for replicas (Materialize).",
1627        false,
1628    );
1629
1630    pub static CLUSTER_SOFTEN_AZ_AFFINITY: VarDefinition = VarDefinition::new(
1631        "cluster_soften_az_affinity",
1632        value!(bool; DEFAULT_SOFTEN_AZ_AFFINITY),
1633        "Whether or not to turn the az-scope node affinity for replicas. \
1634            Note this could violate requests from the user (Materialize).",
1635        false,
1636    );
1637
1638    pub static CLUSTER_SOFTEN_AZ_AFFINITY_WEIGHT: VarDefinition = VarDefinition::new(
1639        "cluster_soften_az_affinity_weight",
1640        value!(i32; DEFAULT_SOFTEN_AZ_AFFINITY_WEIGHT),
1641        "The preference weight for `cluster_soften_az_affinity` (Materialize).",
1642        false,
1643    );
1644
1645    pub static CLUSTER_ALWAYS_USE_DISK: VarDefinition = VarDefinition::new(
1646        "cluster_always_use_disk",
1647        value!(bool; DEFAULT_ALWAYS_USE_DISK),
1648        "Always provisions a replica with disk, regardless of `DISK` DDL option.",
1649        false,
1650    );
1651
1652    const DEFAULT_CLUSTER_ALTER_CHECK_READY_INTERVAL: Duration = Duration::from_secs(3);
1653
1654    pub static CLUSTER_ALTER_CHECK_READY_INTERVAL: VarDefinition = VarDefinition::new(
1655        "cluster_alter_check_ready_interval",
1656        value!(Duration; DEFAULT_CLUSTER_ALTER_CHECK_READY_INTERVAL),
1657        "How often to poll readiness checks for cluster alter",
1658        false,
1659    );
1660
1661    const DEFAULT_CHECK_SCHEDULING_POLICIES_INTERVAL: Duration = Duration::from_secs(3);
1662
1663    pub static CLUSTER_CHECK_SCHEDULING_POLICIES_INTERVAL: VarDefinition = VarDefinition::new(
1664        "cluster_check_scheduling_policies_interval",
1665        value!(Duration; DEFAULT_CHECK_SCHEDULING_POLICIES_INTERVAL),
1666        "How often policies are invoked to automatically start/stop clusters, e.g., \
1667            for REFRESH EVERY materialized views.",
1668        false,
1669    );
1670
1671    pub static CLUSTER_SECURITY_CONTEXT_ENABLED: VarDefinition = VarDefinition::new(
1672        "cluster_security_context_enabled",
1673        value!(bool; DEFAULT_SECURITY_CONTEXT_ENABLED),
1674        "Enables SecurityContext for clusterd instances, restricting capabilities to improve security.",
1675        false,
1676    );
1677
1678    const DEFAULT_CLUSTER_REFRESH_MV_COMPACTION_ESTIMATE: Duration = Duration::from_secs(60);
1679
1680    pub static CLUSTER_REFRESH_MV_COMPACTION_ESTIMATE: VarDefinition = VarDefinition::new(
1681        "cluster_refresh_mv_compaction_estimate",
1682        value!(Duration; DEFAULT_CLUSTER_REFRESH_MV_COMPACTION_ESTIMATE),
1683        "How much time to wait for compaction after a REFRESH MV completes a refresh \
1684            before turning off the refresh cluster. This is needed because Persist does compaction \
1685            only after a write, but refresh MVs do writes only at their refresh times. \
1686            (In the long term, we'd like to remove this configuration and instead wait exactly \
1687            until compaction has settled. We'd need some new Persist API for this.)",
1688        false,
1689    );
1690}
1691
1692/// Macro to simplify creating feature flags, i.e. boolean flags that we use to toggle the
1693/// availability of features.
1694///
1695/// The arguments to `feature_flags!` are:
1696/// - `$name`, which will be the name of the feature flag, in snake_case
1697/// - `$feature_desc`, a human-readable description of the feature
1698/// - `$value`, which if not provided, defaults to `false`
1699///
1700/// Note that not all `VarDefinition<bool>` are feature flags. Feature flags are for variables that:
1701/// - Belong to `SystemVars`, _not_ `SessionVars`
1702/// - Default to false and must be explicitly enabled, or default to `true` and can be explicitly disabled.
1703///
1704/// WARNING / CONTRACT: Syntax-related feature flags must always *enable* behavior. In other words,
1705/// setting a feature flag must make the system more permissive. For example, let's suppose we'd like
1706/// to gate deprecated upsert syntax behind a feature flag. In this case, do not add a feature flag
1707/// like `disable_deprecated_upsert_syntax`, as `disable_deprecated_upsert_syntax = on` would
1708/// _prevent_ the system from parsing the deprecated upsert syntax. Instead, use a feature flag
1709/// like `enable_deprecated_upsert_syntax`.
1710///
1711/// The hazard this protects against is related to reboots after feature flags have been disabled.
1712/// Say someone creates a Kinesis source while `enable_kinesis_sources = on`. Materialize will
1713/// commit this source to the system catalog. Then, suppose we discover a catastrophic bug in
1714/// Kinesis sources and set `enable_kinesis_sources` to `off`. This prevents users from creating
1715/// new Kinesis sources, but leaves the existing Kinesis sources in place. This is because
1716/// disabling a feature flag doesn't remove access to catalog objects created while the feature
1717/// flag was live. On the next reboot, Materialize will proceed to load the Kinesis source from the
1718/// catalog, reparsing and replanning the `CREATE SOURCE` definition and rechecking the
1719/// `enable_kinesis_sources` feature flag along the way. Even though the feature flag has been
1720/// switched to `off`, we need to temporarily re-enable it during parsing and planning to be able
1721/// to boot successfully.
1722///
1723/// Ensuring that all syntax-related feature flags *enable* behavior means that setting all such
1724/// feature flags to `on` during catalog boot has the desired effect.
1725macro_rules! feature_flags {
1726    // Match `$name, $feature_desc, $value`.
1727    (@inner
1728        // The feature flag name.
1729        name: $name:expr,
1730        // The feature flag description.
1731        desc: $desc:literal,
1732        // The feature flag default value.
1733        default: $value:expr,
1734    ) => {
1735        paste::paste!{
1736            // Note that the ServerVar is not directly exported; we expect these to be
1737            // accessible through their FeatureFlag variant.
1738            static [<$name:upper _VAR>]: VarDefinition = VarDefinition::new(
1739                stringify!($name),
1740                value!(bool; $value),
1741                concat!("Whether ", $desc, " is allowed (Materialize)."),
1742                false,
1743            );
1744
1745            pub static [<$name:upper >]: FeatureFlag = FeatureFlag {
1746                flag: &[<$name:upper _VAR>],
1747                feature_desc: $desc,
1748            };
1749        }
1750    };
1751    ($({
1752        // The feature flag name.
1753        name: $name:expr,
1754        // The feature flag description.
1755        desc: $desc:literal,
1756        // The feature flag default value.
1757        default: $value:expr,
1758        // Should the feature be turned on during catalog rehydration when
1759        // parsing a catalog item.
1760        enable_for_item_parsing: $enable_for_item_parsing:expr,
1761    },)+) => {
1762        $(feature_flags! { @inner
1763            name: $name,
1764            desc: $desc,
1765            default: $value,
1766        })+
1767
1768        paste::paste!{
1769            pub static FEATURE_FLAGS: &'static [&'static VarDefinition] = &[
1770                $(  & [<$name:upper _VAR>] , )+
1771            ];
1772        }
1773
1774        paste::paste!{
1775            impl super::SystemVars {
1776                pub fn enable_all_feature_flags_by_default(&mut self) {
1777                    $(
1778                        self.set_default(stringify!($name), super::VarInput::Flat("on"))
1779                            .expect("setting default value must work");
1780                    )+
1781                }
1782
1783                pub fn enable_for_item_parsing(&mut self) {
1784                    $(
1785                        if $enable_for_item_parsing {
1786                            self.set(stringify!($name), super::VarInput::Flat("on"))
1787                                .expect("setting default value must work");
1788                        }
1789                    )+
1790                }
1791
1792                $(
1793                    pub fn [<$name:lower>](&self) -> bool {
1794                        *self.expect_value(&[<$name:upper _VAR>])
1795                    }
1796                )+
1797            }
1798        }
1799    }
1800}
1801
1802feature_flags!(
1803    // Gates for other feature flags
1804    {
1805        name: allow_real_time_recency,
1806        desc: "real time recency",
1807        default: false,
1808        enable_for_item_parsing: true,
1809    },
1810    // Actual feature flags
1811    {
1812        name: enable_binary_date_bin,
1813        desc: "the binary version of date_bin function",
1814        default: false,
1815        enable_for_item_parsing: true,
1816    },
1817    {
1818        name: enable_date_bin_hopping,
1819        desc: "the date_bin_hopping function",
1820        default: false,
1821        enable_for_item_parsing: true,
1822    },
1823    {
1824        name: enable_envelope_debezium_in_subscribe,
1825        desc: "`ENVELOPE DEBEZIUM (KEY (..))`",
1826        default: false,
1827        enable_for_item_parsing: true,
1828    },
1829    {
1830        name: enable_envelope_materialize,
1831        desc: "ENVELOPE MATERIALIZE",
1832        default: false,
1833        enable_for_item_parsing: true,
1834    },
1835    {
1836        name: enable_explain_pushdown,
1837        desc: "EXPLAIN FILTER PUSHDOWN",
1838        default: true,
1839        enable_for_item_parsing: true,
1840    },
1841    {
1842        name: enable_index_options,
1843        desc: "INDEX OPTIONS",
1844        default: false,
1845        enable_for_item_parsing: true,
1846    },
1847    {
1848        name: enable_list_length_max,
1849        desc: "the list_length_max function",
1850        default: false,
1851        enable_for_item_parsing: true,
1852    },
1853    {
1854        name: enable_list_n_layers,
1855        desc: "the list_n_layers function",
1856        default: false,
1857        enable_for_item_parsing: true,
1858    },
1859    {
1860        name: enable_list_remove,
1861        desc: "the list_remove function",
1862        default: false,
1863        enable_for_item_parsing: true,
1864    },
1865    {
1866
1867        name: enable_logical_compaction_window,
1868        desc: "RETAIN HISTORY",
1869        default: false,
1870        enable_for_item_parsing: true,
1871    },
1872    {
1873        name: enable_primary_key_not_enforced,
1874        desc: "PRIMARY KEY NOT ENFORCED",
1875        default: false,
1876        enable_for_item_parsing: true,
1877    },
1878    {
1879        name: enable_collection_partition_by,
1880        desc: "PARTITION BY",
1881        default: false,
1882        enable_for_item_parsing: true,
1883    },
1884    {
1885        name: enable_multi_worker_storage_persist_sink,
1886        desc: "multi-worker storage persist sink",
1887        default: true,
1888        enable_for_item_parsing: true,
1889    },
1890    {
1891        name: enable_persist_streaming_snapshot_and_fetch,
1892        desc: "use the new streaming consolidate for snapshot_and_fetch",
1893        default: false,
1894        enable_for_item_parsing: true,
1895    },
1896    {
1897        name: enable_persist_streaming_compaction,
1898        desc: "use the new streaming consolidate for compaction",
1899        default: false,
1900        enable_for_item_parsing: true,
1901    },
1902    {
1903        name: enable_raise_statement,
1904        desc: "RAISE statement",
1905        default: false,
1906        enable_for_item_parsing: true,
1907    },
1908    {
1909        name: enable_repeat_row,
1910        desc: "the repeat_row function",
1911        default: false,
1912        enable_for_item_parsing: true,
1913    },
1914    {
1915        name: unsafe_enable_table_check_constraint,
1916        desc: "CREATE TABLE with a check constraint",
1917        default: false,
1918        enable_for_item_parsing: true,
1919    },
1920    {
1921        name: unsafe_enable_table_foreign_key,
1922        desc: "CREATE TABLE with a foreign key",
1923        default: false,
1924        enable_for_item_parsing: true,
1925    },
1926    {
1927        name: unsafe_enable_table_keys,
1928        desc: "CREATE TABLE with a primary key or unique constraint",
1929        default: false,
1930        enable_for_item_parsing: true,
1931    },
1932    {
1933        name: unsafe_enable_unorchestrated_cluster_replicas,
1934        desc: "unorchestrated cluster replicas",
1935        default: false,
1936        enable_for_item_parsing: true,
1937    },
1938    {
1939        name: unsafe_enable_unstable_dependencies,
1940        desc: "depending on unstable objects",
1941        default: false,
1942        enable_for_item_parsing: true,
1943    },
1944    {
1945        name: enable_disk_cluster_replicas,
1946        desc: "`WITH (DISK)` for cluster replicas",
1947        default: true,
1948        enable_for_item_parsing: true,
1949    },
1950    {
1951        name: enable_within_timestamp_order_by_in_subscribe,
1952        desc: "`WITHIN TIMESTAMP ORDER BY ..`",
1953        default: false,
1954        enable_for_item_parsing: true,
1955    },
1956    {
1957        name: enable_cardinality_estimates,
1958        desc: "join planning with cardinality estimates",
1959        default: false,
1960        enable_for_item_parsing: true,
1961    },
1962    {
1963        name: enable_connection_validation_syntax,
1964        desc: "CREATE CONNECTION .. WITH (VALIDATE) and VALIDATE CONNECTION syntax",
1965        default: true,
1966        enable_for_item_parsing: true,
1967    },
1968    {
1969        name: enable_alter_set_cluster,
1970        desc: "ALTER ... SET CLUSTER syntax",
1971        default: false,
1972        enable_for_item_parsing: true,
1973    },
1974    {
1975        name: unsafe_enable_unsafe_functions,
1976        desc: "executing potentially dangerous functions",
1977        default: false,
1978        enable_for_item_parsing: true,
1979    },
1980    {
1981        name: enable_managed_cluster_availability_zones,
1982        desc: "MANAGED, AVAILABILITY ZONES syntax",
1983        default: false,
1984        enable_for_item_parsing: true,
1985    },
1986    {
1987        name: statement_logging_use_reproducible_rng,
1988        desc: "statement logging with reproducible RNG",
1989        default: false,
1990        enable_for_item_parsing: true,
1991    },
1992    {
1993        name: enable_notices_for_index_already_exists,
1994        desc: "emitting notices for IndexAlreadyExists (doesn't affect EXPLAIN)",
1995        default: true,
1996        enable_for_item_parsing: true,
1997    },
1998    {
1999        name: enable_notices_for_index_too_wide_for_literal_constraints,
2000        desc: "emitting notices for IndexTooWideForLiteralConstraints (doesn't affect EXPLAIN)",
2001        default: false,
2002        enable_for_item_parsing: true,
2003    },
2004    {
2005        name: enable_notices_for_index_empty_key,
2006        desc: "emitting notices for indexes with an empty key (doesn't affect EXPLAIN)",
2007        default: true,
2008        enable_for_item_parsing: true,
2009    },
2010    {
2011        name: enable_alter_swap,
2012        desc: "the ALTER SWAP feature for objects",
2013        default: true,
2014        enable_for_item_parsing: true,
2015    },
2016    {
2017        name: enable_new_outer_join_lowering,
2018        desc: "new outer join lowering",
2019        default: true,
2020        enable_for_item_parsing: false,
2021    },
2022    {
2023        name: enable_time_at_time_zone,
2024        desc: "use of AT TIME ZONE or timezone() with time type",
2025        default: false,
2026        enable_for_item_parsing: true,
2027    },
2028    {
2029        name: enable_load_generator_key_value,
2030        desc: "Create a LOAD GENERATOR KEY VALUE",
2031        default: false,
2032        enable_for_item_parsing: false,
2033    },
2034    {
2035        name: enable_expressions_in_limit_syntax,
2036        desc: "LIMIT <expr> syntax",
2037        default: true,
2038        enable_for_item_parsing: true,
2039    },
2040    {
2041        name: enable_mz_notices,
2042        desc: "Populate the contents of `mz_internal.mz_notices`",
2043        default: true,
2044        enable_for_item_parsing: false,
2045    },
2046    {
2047        name: enable_eager_delta_joins,
2048        desc:
2049            "eager delta joins",
2050        default: false,
2051        enable_for_item_parsing: false,
2052    },
2053    {
2054        name: enable_off_thread_optimization,
2055        desc: "use off-thread optimization in `CREATE` statements",
2056        default: true,
2057        enable_for_item_parsing: false,
2058    },
2059    {
2060        name: enable_refresh_every_mvs,
2061        desc: "REFRESH EVERY and REFRESH AT materialized views",
2062        default: false,
2063        enable_for_item_parsing: true,
2064    },
2065    {
2066        name: enable_cluster_schedule_refresh,
2067        desc: "`SCHEDULE = ON REFRESH` cluster option",
2068        default: false,
2069        enable_for_item_parsing: true,
2070    },
2071    {
2072        name: enable_reduce_mfp_fusion,
2073        desc: "fusion of MFPs in reductions",
2074        default: true,
2075        enable_for_item_parsing: false,
2076    },
2077    {
2078        name: enable_worker_core_affinity,
2079        desc: "set core affinity for replica worker threads",
2080        default: false,
2081        enable_for_item_parsing: false,
2082    },
2083    {
2084        name: enable_copy_to_expr,
2085        desc: "COPY ... TO 's3://...'",
2086        default: true,
2087        enable_for_item_parsing: false,
2088    },
2089    {
2090        name: enable_session_timelines,
2091        desc: "strong session serializable isolation levels",
2092        default: false,
2093        enable_for_item_parsing: false,
2094    },
2095    {
2096        name: enable_variadic_left_join_lowering,
2097        desc: "Enable joint HIR ⇒ MIR lowering of stacks of left joins",
2098        default: false,
2099        enable_for_item_parsing: false,
2100    },
2101    {
2102        name: enable_redacted_test_option,
2103        desc: "Enable useless option to test value redaction",
2104        default: false,
2105        enable_for_item_parsing: true,
2106    },
2107    {
2108        name: enable_letrec_fixpoint_analysis,
2109        desc: "Enable Lattice-based fixpoint iteration on LetRec nodes in the Analysis framework",
2110        default: true, // This is just a failsafe switch for the deployment of materialize#25591.
2111        enable_for_item_parsing: false,
2112    },
2113    {
2114        name: enable_kafka_sink_headers,
2115        desc: "Enable the HEADERS option for Kafka sinks",
2116        default: false,
2117        enable_for_item_parsing: true,
2118    },
2119    {
2120        name: enable_unlimited_retain_history,
2121        desc: "Disable limits on RETAIN HISTORY (below 1s default, and 0 disables compaction).",
2122        default: false,
2123        enable_for_item_parsing: true,
2124    },
2125    {
2126        name: enable_envelope_upsert_inline_errors,
2127        desc: "The VALUE DECODING ERRORS = INLINE option on ENVELOPE UPSERT",
2128        default: false,
2129        enable_for_item_parsing: true,
2130    },
2131    {
2132        name: enable_alter_table_add_column,
2133        desc: "Enable ALTER TABLE ... ADD COLUMN ...",
2134        default: false,
2135        enable_for_item_parsing: false,
2136    },
2137    {
2138        name: enable_zero_downtime_cluster_reconfiguration,
2139        desc: "Enable zero-downtime reconfiguration for alter cluster",
2140        default: false,
2141        enable_for_item_parsing: false,
2142    },
2143    {
2144        name: enable_aws_msk_iam_auth,
2145        desc: "Enable AWS MSK IAM authentication for Kafka connections",
2146        default: false,
2147        enable_for_item_parsing: true,
2148    },
2149    {
2150        name: enable_clock_load_generator,
2151        desc: "Enable the clock load generator",
2152        default: false,
2153        enable_for_item_parsing: true,
2154    },
2155    {
2156        name: enable_yugabyte_connection,
2157        desc: "Create a YUGABYTE connection",
2158        default: false,
2159        enable_for_item_parsing: false,
2160    },
2161    {
2162        name: enable_continual_task_create,
2163        desc: "CREATE CONTINUAL TASK",
2164        default: false,
2165        enable_for_item_parsing: true,
2166    },
2167    {
2168        name: enable_continual_task_transform,
2169        desc: "CREATE CONTINUAL TASK .. FROM TRANSFORM .. USING",
2170        default: false,
2171        enable_for_item_parsing: true,
2172    },
2173    {
2174        name: enable_continual_task_retain,
2175        desc: "CREATE CONTINUAL TASK .. FROM RETAIN .. WHILE",
2176        default: false,
2177        enable_for_item_parsing: true,
2178    },
2179    {
2180        name: enable_network_policies,
2181        desc: "ENABLE NETWORK POLICIES",
2182        default: false,
2183        enable_for_item_parsing: true,
2184    },
2185    {
2186        name: enable_create_table_from_source,
2187        desc: "Whether to allow CREATE TABLE .. FROM SOURCE syntax.",
2188        default: false,
2189        enable_for_item_parsing: true,
2190    },
2191    {
2192        name: enable_copy_from_remote,
2193        desc: "Whether to allow COPY FROM <url>.",
2194        default: false,
2195        enable_for_item_parsing: false,
2196    },
2197    {
2198        name: enable_join_prioritize_arranged,
2199        desc: "Whether join planning should prioritize already-arranged keys over keys with more fields.",
2200        default: true,
2201        enable_for_item_parsing: false,
2202    },
2203    {
2204        name: enable_sql_server_source,
2205        desc: "Creating a SQL SERVER source",
2206        default: false,
2207        enable_for_item_parsing: false,
2208    },
2209    {
2210        name: enable_projection_pushdown_after_relation_cse,
2211        desc: "Run ProjectionPushdown one more time after the last RelationCSE.",
2212        default: true,
2213        enable_for_item_parsing: false,
2214    },
2215    {
2216        name: enable_less_reduce_in_eqprop,
2217        desc: "Run MSE::reduce in EquivalencePropagation only if reduce_expr changed something.",
2218        default: true,
2219        enable_for_item_parsing: false,
2220    },
2221    {
2222        name: enable_dequadratic_eqprop_map,
2223        desc: "Skip the quadratic part of EquivalencePropagation's handling of Map.",
2224        default: true,
2225        enable_for_item_parsing: false,
2226    },
2227);
2228
2229impl From<&super::SystemVars> for OptimizerFeatures {
2230    fn from(vars: &super::SystemVars) -> Self {
2231        Self {
2232            enable_consolidate_after_union_negate: vars.enable_consolidate_after_union_negate(),
2233            enable_eager_delta_joins: vars.enable_eager_delta_joins(),
2234            enable_new_outer_join_lowering: vars.enable_new_outer_join_lowering(),
2235            enable_reduce_mfp_fusion: vars.enable_reduce_mfp_fusion(),
2236            enable_variadic_left_join_lowering: vars.enable_variadic_left_join_lowering(),
2237            enable_letrec_fixpoint_analysis: vars.enable_letrec_fixpoint_analysis(),
2238            enable_cardinality_estimates: vars.enable_cardinality_estimates(),
2239            enable_reduce_reduction: vars.enable_reduce_reduction(),
2240            persist_fast_path_limit: vars.persist_fast_path_limit(),
2241            reoptimize_imported_views: false,
2242            enable_join_prioritize_arranged: vars.enable_join_prioritize_arranged(),
2243            enable_projection_pushdown_after_relation_cse: vars
2244                .enable_projection_pushdown_after_relation_cse(),
2245            enable_less_reduce_in_eqprop: vars.enable_less_reduce_in_eqprop(),
2246            enable_dequadratic_eqprop_map: vars.enable_dequadratic_eqprop_map(),
2247        }
2248    }
2249}