mz_sql/session/vars/
definitions.rs

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