Skip to main content

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