1use std::collections::{BTreeMap, BTreeSet};
30use std::num::NonZeroUsize;
31use std::str::FromStr;
32use std::time::Duration;
33
34use chrono::{DateTime, Utc};
35use enum_kinds::EnumKind;
36use ipnet::IpNet;
37use maplit::btreeset;
38use mz_adapter_types::compaction::CompactionWindow;
39use mz_controller_types::{ClusterId, ReplicaId};
40use mz_expr::{CollectionPlan, ColumnOrder, MapFilterProject, MirScalarExpr, RowSetFinishing};
41use mz_ore::now::{self, NOW_ZERO};
42use mz_pgcopy::CopyFormatParams;
43use mz_repr::adt::mz_acl_item::{AclMode, MzAclItem};
44use mz_repr::explain::{ExplainConfig, ExplainFormat};
45use mz_repr::network_policy_id::NetworkPolicyId;
46use mz_repr::optimize::OptimizerFeatureOverrides;
47use mz_repr::refresh_schedule::RefreshSchedule;
48use mz_repr::role_id::RoleId;
49use mz_repr::{
50 CatalogItemId, ColumnIndex, ColumnName, Diff, GlobalId, RelationDesc, ReprColumnType, Row,
51 SqlColumnType, SqlRelationType, SqlScalarType, Timestamp, VersionedRelationDesc,
52};
53use mz_sql_parser::ast::{
54 AlterSourceAddSubsourceOption, ClusterAlterOptionValue, ConnectionOptionName, CreateSinkOption,
55 CreateSinkOptionName, QualifiedReplica, RawDataType, SelectStatement,
56 TransactionIsolationLevel, TransactionMode, UnresolvedItemName, Value, WithOptionValue,
57};
58use mz_ssh_util::keys::SshKeyPair;
59use mz_storage_types::connections::aws::AwsConnection;
60use mz_storage_types::connections::gcp::{GcpConnection, GcpServiceAccountKeyTokenUri};
61use mz_storage_types::connections::inline::ReferencedConnection;
62use mz_storage_types::connections::{
63 AwsPrivatelinkConnection, CsrConnection, GlueSchemaRegistryConnection,
64 IcebergCatalogConnection, KafkaConnection, MySqlConnection, PostgresConnection,
65 SqlServerConnectionDetails, SshConnection,
66};
67use mz_storage_types::instances::StorageInstanceId;
68use mz_storage_types::sinks::{S3SinkFormat, SinkEnvelope, StorageSinkConnection};
69use mz_storage_types::sources::{
70 SourceDesc, SourceExportDataConfig, SourceExportDetails, Timeline,
71};
72use proptest_derive::Arbitrary;
73use serde::{Deserialize, Serialize};
74
75use crate::ast::{
76 ExplainStage, Expr, FetchDirection, NoticeSeverity, Raw, Statement, StatementKind,
77 TransactionAccessMode,
78};
79use crate::catalog::{
80 CatalogType, DefaultPrivilegeAclItem, DefaultPrivilegeObject, IdReference, ObjectType,
81 RoleAttributesRaw,
82};
83use crate::names::{
84 Aug, CommentObjectId, DependencyIds, FullItemName, ObjectId, QualifiedItemName,
85 ResolvedDatabaseSpecifier, ResolvedIds, SchemaSpecifier, SystemObjectId,
86};
87
88pub(crate) mod error;
89pub(crate) mod explain;
90pub(crate) mod hir;
91pub(crate) mod literal;
92pub(crate) mod lowering;
93pub(crate) mod notice;
94pub(crate) mod plan_utils;
95pub(crate) mod query;
96pub(crate) mod scope;
97pub(crate) mod side_effecting_func;
98pub(crate) mod statement;
99pub(crate) mod transform_ast;
100pub(crate) mod transform_hir;
101pub(crate) mod typeconv;
102pub use typeconv::{
103 CastContext, plan_hypothetical_cast_with_failure_mode, valid_cast_base_type_pairs,
104};
105pub(crate) mod with_options;
106
107use crate::plan;
108use crate::plan::statement::ddl::ClusterAlterUntilReadyOptionExtracted;
109use crate::plan::with_options::OptionalDuration;
110pub use error::PlanError;
111pub use explain::normalize_subqueries;
112pub use hir::{
113 AggregateExpr, CoercibleScalarExpr, Hir, HirRelationExpr, HirScalarExpr, JoinKind,
114 WindowExprType,
115};
116pub use lowering::Config as HirToMirConfig;
117pub use notice::PlanNotice;
118pub use query::{
119 ExprContext, QueryContext, QueryLifetime, is_supported_collation, scalar_type_from_catalog,
120};
121pub use scope::Scope;
122pub use side_effecting_func::SideEffectingFunc;
123pub use statement::ddl::{
124 AlterSourceAddSubsourceOptionExtracted, METRIC_SINK_CURATED_PREFIX_MARKER,
125 MySqlConfigOptionExtracted, PgConfigOptionExtracted, PlannedAlterRoleOption,
126 PlannedRoleAttributes, PlannedRoleVariable, SqlServerConfigOptionExtracted,
127 validate_metric_sink_desc, validate_metric_sink_prefix, validate_user_metric_sink_prefix,
128};
129pub use statement::{
130 StatementClassification, StatementContext, StatementDesc, describe, plan, plan_copy_from,
131 resolve_cluster_for_materialized_view,
132};
133pub use with_options::TryFromValue;
134
135use self::statement::ddl::ClusterAlterOptionExtracted;
136
137#[derive(Debug, EnumKind)]
139#[enum_kind(PlanKind)]
140pub enum Plan {
141 CreateConnection(CreateConnectionPlan),
142 CreateDatabase(CreateDatabasePlan),
143 CreateSchema(CreateSchemaPlan),
144 CreateRole(CreateRolePlan),
145 CreateCluster(CreateClusterPlan),
146 CreateClusterReplica(CreateClusterReplicaPlan),
147 CreateSource(CreateSourcePlan),
148 CreateSources(Vec<CreateSourcePlanBundle>),
149 CreateSecret(CreateSecretPlan),
150 CreateSink(CreateSinkPlan),
151 CreateTable(CreateTablePlan),
152 CreateView(CreateViewPlan),
153 CreateMaterializedView(CreateMaterializedViewPlan),
154 CreateNetworkPolicy(CreateNetworkPolicyPlan),
155 CreateIndex(CreateIndexPlan),
156 CreateMetricSink(CreateMetricSinkPlan),
157 CreateType(CreateTypePlan),
158 Comment(CommentPlan),
159 DiscardTemp,
160 DiscardAll,
161 DropObjects(DropObjectsPlan),
162 DropOwned(DropOwnedPlan),
163 EmptyQuery,
164 ShowAllVariables,
165 ShowCreate(ShowCreatePlan),
166 ShowColumns(ShowColumnsPlan),
167 ShowVariable(ShowVariablePlan),
168 InspectShard(InspectShardPlan),
169 SetVariable(SetVariablePlan),
170 ResetVariable(ResetVariablePlan),
171 SetTransaction(SetTransactionPlan),
172 StartTransaction(StartTransactionPlan),
173 CommitTransaction(CommitTransactionPlan),
174 AbortTransaction(AbortTransactionPlan),
175 Select(SelectPlan),
176 Subscribe(SubscribePlan),
177 CopyFrom(CopyFromPlan),
178 CopyTo(CopyToPlan),
179 ExplainPlan(ExplainPlanPlan),
180 ExplainPushdown(ExplainPushdownPlan),
181 ExplainTimestamp(ExplainTimestampPlan),
182 ExplainSinkSchema(ExplainSinkSchemaPlan),
183 Insert(InsertPlan),
184 AlterCluster(AlterClusterPlan),
185 AlterClusterSwap(AlterClusterSwapPlan),
186 AlterNoop(AlterNoopPlan),
187 AlterSetCluster(AlterSetClusterPlan),
188 AlterConnection(AlterConnectionPlan),
189 AlterSource(AlterSourcePlan),
190 AlterClusterRename(AlterClusterRenamePlan),
191 AlterClusterReplicaRename(AlterClusterReplicaRenamePlan),
192 AlterItemRename(AlterItemRenamePlan),
193 AlterSchemaRename(AlterSchemaRenamePlan),
194 AlterSchemaSwap(AlterSchemaSwapPlan),
195 AlterSecret(AlterSecretPlan),
196 AlterSink(AlterSinkPlan),
197 AlterSystemSet(AlterSystemSetPlan),
198 AlterSystemReset(AlterSystemResetPlan),
199 AlterSystemResetAll(AlterSystemResetAllPlan),
200 AlterRole(AlterRolePlan),
201 AlterOwner(AlterOwnerPlan),
202 AlterTableAddColumn(AlterTablePlan),
203 AlterMaterializedViewApplyReplacement(AlterMaterializedViewApplyReplacementPlan),
204 AlterNetworkPolicy(AlterNetworkPolicyPlan),
205 Declare(DeclarePlan),
206 Fetch(FetchPlan),
207 Close(ClosePlan),
208 ReadThenWrite(ReadThenWritePlan),
209 Prepare(PreparePlan),
210 Execute(ExecutePlan),
211 Deallocate(DeallocatePlan),
212 Raise(RaisePlan),
213 GrantRole(GrantRolePlan),
214 RevokeRole(RevokeRolePlan),
215 GrantPrivileges(GrantPrivilegesPlan),
216 RevokePrivileges(RevokePrivilegesPlan),
217 AlterDefaultPrivileges(AlterDefaultPrivilegesPlan),
218 ReassignOwned(ReassignOwnedPlan),
219 SideEffectingFunc(SideEffectingFunc),
220 ValidateConnection(ValidateConnectionPlan),
221 AlterRetainHistory(AlterRetainHistoryPlan),
222 AlterSourceTimestampInterval(AlterSourceTimestampIntervalPlan),
223}
224
225impl Plan {
226 pub fn generated_from(stmt: &StatementKind) -> &'static [PlanKind] {
229 match stmt {
230 StatementKind::AlterCluster => &[PlanKind::AlterNoop, PlanKind::AlterCluster],
231 StatementKind::AlterConnection => &[PlanKind::AlterNoop, PlanKind::AlterConnection],
232 StatementKind::AlterDefaultPrivileges => &[PlanKind::AlterDefaultPrivileges],
233 StatementKind::AlterIndex => &[PlanKind::AlterRetainHistory, PlanKind::AlterNoop],
234 StatementKind::AlterObjectRename => &[
235 PlanKind::AlterClusterRename,
236 PlanKind::AlterClusterReplicaRename,
237 PlanKind::AlterItemRename,
238 PlanKind::AlterSchemaRename,
239 PlanKind::AlterNoop,
240 ],
241 StatementKind::AlterObjectSwap => &[
242 PlanKind::AlterClusterSwap,
243 PlanKind::AlterSchemaSwap,
244 PlanKind::AlterNoop,
245 ],
246 StatementKind::AlterRole => &[PlanKind::AlterRole],
247 StatementKind::AlterNetworkPolicy => &[PlanKind::AlterNetworkPolicy],
248 StatementKind::AlterSecret => &[PlanKind::AlterNoop, PlanKind::AlterSecret],
249 StatementKind::AlterSetCluster => &[PlanKind::AlterNoop, PlanKind::AlterSetCluster],
250 StatementKind::AlterSink => &[PlanKind::AlterNoop, PlanKind::AlterSink],
251 StatementKind::AlterSource => &[
252 PlanKind::AlterNoop,
253 PlanKind::AlterSource,
254 PlanKind::AlterRetainHistory,
255 PlanKind::AlterSourceTimestampInterval,
256 ],
257 StatementKind::AlterSystemReset => &[PlanKind::AlterNoop, PlanKind::AlterSystemReset],
258 StatementKind::AlterSystemResetAll => {
259 &[PlanKind::AlterNoop, PlanKind::AlterSystemResetAll]
260 }
261 StatementKind::AlterSystemSet => &[PlanKind::AlterNoop, PlanKind::AlterSystemSet],
262 StatementKind::AlterOwner => &[PlanKind::AlterNoop, PlanKind::AlterOwner],
263 StatementKind::AlterTableAddColumn => {
264 &[PlanKind::AlterNoop, PlanKind::AlterTableAddColumn]
265 }
266 StatementKind::AlterMaterializedViewApplyReplacement => &[
267 PlanKind::AlterNoop,
268 PlanKind::AlterMaterializedViewApplyReplacement,
269 ],
270 StatementKind::Close => &[PlanKind::Close],
271 StatementKind::Comment => &[PlanKind::Comment],
272 StatementKind::Commit => &[PlanKind::CommitTransaction],
273 StatementKind::Copy => &[
274 PlanKind::CopyFrom,
275 PlanKind::Select,
276 PlanKind::Subscribe,
277 PlanKind::CopyTo,
278 ],
279 StatementKind::CreateCluster => &[PlanKind::CreateCluster],
280 StatementKind::CreateClusterReplica => &[PlanKind::CreateClusterReplica],
281 StatementKind::CreateConnection => &[PlanKind::CreateConnection],
282 StatementKind::CreateDatabase => &[PlanKind::CreateDatabase],
283 StatementKind::CreateIndex => &[PlanKind::CreateIndex],
284 StatementKind::CreateNetworkPolicy => &[PlanKind::CreateNetworkPolicy],
285 StatementKind::CreateMaterializedView => &[PlanKind::CreateMaterializedView],
286 StatementKind::CreateRole => &[PlanKind::CreateRole],
287 StatementKind::CreateSchema => &[PlanKind::CreateSchema],
288 StatementKind::CreateSecret => &[PlanKind::CreateSecret],
289 StatementKind::CreateSink => &[PlanKind::CreateSink],
290 StatementKind::CreateMetricSink => &[PlanKind::CreateMetricSink],
291 StatementKind::CreateSource | StatementKind::CreateSubsource => {
292 &[PlanKind::CreateSource]
293 }
294 StatementKind::CreateWebhookSource => &[PlanKind::CreateSource, PlanKind::CreateTable],
295 StatementKind::CreateTable => &[PlanKind::CreateTable],
296 StatementKind::CreateTableFromSource => &[PlanKind::CreateTable],
297 StatementKind::CreateType => &[PlanKind::CreateType],
298 StatementKind::CreateView => &[PlanKind::CreateView],
299 StatementKind::Deallocate => &[PlanKind::Deallocate],
300 StatementKind::Declare => &[PlanKind::Declare],
301 StatementKind::Delete => &[PlanKind::ReadThenWrite],
302 StatementKind::Discard => &[PlanKind::DiscardAll, PlanKind::DiscardTemp],
303 StatementKind::DropObjects => &[PlanKind::DropObjects],
304 StatementKind::DropOwned => &[PlanKind::DropOwned],
305 StatementKind::Execute => &[PlanKind::Execute],
306 StatementKind::ExplainPlan => &[PlanKind::ExplainPlan],
307 StatementKind::ExplainPushdown => &[PlanKind::ExplainPushdown],
308 StatementKind::ExplainAnalyzeObject => &[PlanKind::Select],
309 StatementKind::ExplainAnalyzeCluster => &[PlanKind::Select],
310 StatementKind::ExplainTimestamp => &[PlanKind::ExplainTimestamp],
311 StatementKind::ExplainSinkSchema => &[PlanKind::ExplainSinkSchema],
312 StatementKind::Fetch => &[PlanKind::Fetch],
313 StatementKind::GrantPrivileges => &[PlanKind::GrantPrivileges],
314 StatementKind::GrantRole => &[PlanKind::GrantRole],
315 StatementKind::Insert => &[PlanKind::Insert],
316 StatementKind::Prepare => &[PlanKind::Prepare],
317 StatementKind::Raise => &[PlanKind::Raise],
318 StatementKind::ReassignOwned => &[PlanKind::ReassignOwned],
319 StatementKind::ResetVariable => &[PlanKind::ResetVariable],
320 StatementKind::RevokePrivileges => &[PlanKind::RevokePrivileges],
321 StatementKind::RevokeRole => &[PlanKind::RevokeRole],
322 StatementKind::Rollback => &[PlanKind::AbortTransaction],
323 StatementKind::Select => &[PlanKind::Select, PlanKind::SideEffectingFunc],
324 StatementKind::SetTransaction => &[PlanKind::SetTransaction],
325 StatementKind::SetVariable => &[PlanKind::SetVariable],
326 StatementKind::Show => &[
327 PlanKind::Select,
328 PlanKind::ShowVariable,
329 PlanKind::ShowCreate,
330 PlanKind::ShowColumns,
331 PlanKind::ShowAllVariables,
332 PlanKind::InspectShard,
333 ],
334 StatementKind::StartTransaction => &[PlanKind::StartTransaction],
335 StatementKind::Subscribe => &[PlanKind::Subscribe],
336 StatementKind::Update => &[PlanKind::ReadThenWrite],
337 StatementKind::ValidateConnection => &[PlanKind::ValidateConnection],
338 StatementKind::AlterRetainHistory => &[PlanKind::AlterRetainHistory],
339 StatementKind::ExecuteUnitTest => &[],
340 }
341 }
342
343 pub fn name(&self) -> &str {
345 match self {
346 Plan::CreateConnection(_) => "create connection",
347 Plan::CreateDatabase(_) => "create database",
348 Plan::CreateSchema(_) => "create schema",
349 Plan::CreateRole(_) => "create role",
350 Plan::CreateCluster(_) => "create cluster",
351 Plan::CreateClusterReplica(_) => "create cluster replica",
352 Plan::CreateSource(_) => "create source",
353 Plan::CreateSources(_) => "create source",
354 Plan::CreateSecret(_) => "create secret",
355 Plan::CreateSink(_) => "create sink",
356 Plan::CreateTable(_) => "create table",
357 Plan::CreateView(_) => "create view",
358 Plan::CreateMaterializedView(_) => "create materialized view",
359 Plan::CreateIndex(_) => "create index",
360 Plan::CreateMetricSink(_) => "create metric sink",
361 Plan::CreateType(_) => "create type",
362 Plan::CreateNetworkPolicy(_) => "create network policy",
363 Plan::Comment(_) => "comment",
364 Plan::DiscardTemp => "discard temp",
365 Plan::DiscardAll => "discard all",
366 Plan::DropObjects(plan) => match plan.object_type {
367 ObjectType::Table => "drop table",
368 ObjectType::View => "drop view",
369 ObjectType::MaterializedView => "drop materialized view",
370 ObjectType::Source => "drop source",
371 ObjectType::Sink => "drop sink",
372 ObjectType::MetricSink => "drop metric sink",
373 ObjectType::Index => "drop index",
374 ObjectType::Type => "drop type",
375 ObjectType::Role => "drop roles",
376 ObjectType::Cluster => "drop clusters",
377 ObjectType::ClusterReplica => "drop cluster replicas",
378 ObjectType::Secret => "drop secret",
379 ObjectType::Connection => "drop connection",
380 ObjectType::Database => "drop database",
381 ObjectType::Schema => "drop schema",
382 ObjectType::Func => "drop function",
383 ObjectType::NetworkPolicy => "drop network policy",
384 },
385 Plan::DropOwned(_) => "drop owned",
386 Plan::EmptyQuery => "do nothing",
387 Plan::ShowAllVariables => "show all variables",
388 Plan::ShowCreate(_) => "show create",
389 Plan::ShowColumns(_) => "show columns",
390 Plan::ShowVariable(_) => "show variable",
391 Plan::InspectShard(_) => "inspect shard",
392 Plan::SetVariable(_) => "set variable",
393 Plan::ResetVariable(_) => "reset variable",
394 Plan::SetTransaction(_) => "set transaction",
395 Plan::StartTransaction(_) => "start transaction",
396 Plan::CommitTransaction(_) => "commit",
397 Plan::AbortTransaction(_) => "abort",
398 Plan::Select(_) => "select",
399 Plan::Subscribe(_) => "subscribe",
400 Plan::CopyFrom(_) => "copy from",
401 Plan::CopyTo(_) => "copy to",
402 Plan::ExplainPlan(_) => "explain plan",
403 Plan::ExplainPushdown(_) => "EXPLAIN FILTER PUSHDOWN",
404 Plan::ExplainTimestamp(_) => "explain timestamp",
405 Plan::ExplainSinkSchema(_) => "explain schema",
406 Plan::Insert(_) => "insert",
407 Plan::AlterNoop(plan) => match plan.object_type {
408 ObjectType::Table => "alter table",
409 ObjectType::View => "alter view",
410 ObjectType::MaterializedView => "alter materialized view",
411 ObjectType::Source => "alter source",
412 ObjectType::Sink => "alter sink",
413 ObjectType::MetricSink => "alter metric sink",
414 ObjectType::Index => "alter index",
415 ObjectType::Type => "alter type",
416 ObjectType::Role => "alter role",
417 ObjectType::Cluster => "alter cluster",
418 ObjectType::ClusterReplica => "alter cluster replica",
419 ObjectType::Secret => "alter secret",
420 ObjectType::Connection => "alter connection",
421 ObjectType::Database => "alter database",
422 ObjectType::Schema => "alter schema",
423 ObjectType::Func => "alter function",
424 ObjectType::NetworkPolicy => "alter network policy",
425 },
426 Plan::AlterCluster(_) => "alter cluster",
427 Plan::AlterClusterRename(_) => "alter cluster rename",
428 Plan::AlterClusterSwap(_) => "alter cluster swap",
429 Plan::AlterClusterReplicaRename(_) => "alter cluster replica rename",
430 Plan::AlterSetCluster(_) => "alter set cluster",
431 Plan::AlterConnection(_) => "alter connection",
432 Plan::AlterSource(_) => "alter source",
433 Plan::AlterItemRename(_) => "rename item",
434 Plan::AlterSchemaRename(_) => "alter rename schema",
435 Plan::AlterSchemaSwap(_) => "alter swap schema",
436 Plan::AlterSecret(_) => "alter secret",
437 Plan::AlterSink(_) => "alter sink",
438 Plan::AlterSystemSet(_) => "alter system",
439 Plan::AlterSystemReset(_) => "alter system",
440 Plan::AlterSystemResetAll(_) => "alter system",
441 Plan::AlterRole(_) => "alter role",
442 Plan::AlterNetworkPolicy(_) => "alter network policy",
443 Plan::AlterOwner(plan) => match plan.object_type {
444 ObjectType::Table => "alter table owner",
445 ObjectType::View => "alter view owner",
446 ObjectType::MaterializedView => "alter materialized view owner",
447 ObjectType::Source => "alter source owner",
448 ObjectType::Sink => "alter sink owner",
449 ObjectType::MetricSink => "alter metric sink owner",
450 ObjectType::Index => "alter index owner",
451 ObjectType::Type => "alter type owner",
452 ObjectType::Role => "alter role owner",
453 ObjectType::Cluster => "alter cluster owner",
454 ObjectType::ClusterReplica => "alter cluster replica owner",
455 ObjectType::Secret => "alter secret owner",
456 ObjectType::Connection => "alter connection owner",
457 ObjectType::Database => "alter database owner",
458 ObjectType::Schema => "alter schema owner",
459 ObjectType::Func => "alter function owner",
460 ObjectType::NetworkPolicy => "alter network policy owner",
461 },
462 Plan::AlterTableAddColumn(_) => "alter table add column",
463 Plan::AlterMaterializedViewApplyReplacement(_) => {
464 "alter materialized view apply replacement"
465 }
466 Plan::Declare(_) => "declare",
467 Plan::Fetch(_) => "fetch",
468 Plan::Close(_) => "close",
469 Plan::ReadThenWrite(plan) => match plan.kind {
470 MutationKind::Insert => "insert into select",
471 MutationKind::Update => "update",
472 MutationKind::Delete => "delete",
473 },
474 Plan::Prepare(_) => "prepare",
475 Plan::Execute(_) => "execute",
476 Plan::Deallocate(_) => "deallocate",
477 Plan::Raise(_) => "raise",
478 Plan::GrantRole(_) => "grant role",
479 Plan::RevokeRole(_) => "revoke role",
480 Plan::GrantPrivileges(_) => "grant privilege",
481 Plan::RevokePrivileges(_) => "revoke privilege",
482 Plan::AlterDefaultPrivileges(_) => "alter default privileges",
483 Plan::ReassignOwned(_) => "reassign owned",
484 Plan::SideEffectingFunc(_) => "side effecting func",
485 Plan::ValidateConnection(_) => "validate connection",
486 Plan::AlterRetainHistory(_) => "alter retain history",
487 Plan::AlterSourceTimestampInterval(_) => "alter source timestamp interval",
488 }
489 }
490
491 pub fn allowed_in_read_only(&self) -> bool {
497 match self {
498 Plan::SetVariable(_) => true,
501 Plan::ResetVariable(_) => true,
502 Plan::SetTransaction(_) => true,
503 Plan::StartTransaction(_) => true,
504 Plan::CommitTransaction(_) => true,
505 Plan::AbortTransaction(_) => true,
506 Plan::Select(_) => true,
507 Plan::EmptyQuery => true,
508 Plan::ShowAllVariables => true,
509 Plan::ShowCreate(_) => true,
510 Plan::ShowColumns(_) => true,
511 Plan::ShowVariable(_) => true,
512 Plan::InspectShard(_) => true,
513 Plan::Subscribe(_) => true,
514 Plan::CopyTo(_) => true,
515 Plan::ExplainPlan(_) => true,
516 Plan::ExplainPushdown(_) => true,
517 Plan::ExplainTimestamp(_) => true,
518 Plan::ExplainSinkSchema(_) => true,
519 Plan::ValidateConnection(_) => true,
520 _ => false,
521 }
522 }
523}
524
525#[derive(Debug)]
526pub struct StartTransactionPlan {
527 pub access: Option<TransactionAccessMode>,
528 pub isolation_level: Option<TransactionIsolationLevel>,
529}
530
531#[derive(Debug)]
532pub enum TransactionType {
533 Explicit,
534 Implicit,
535}
536
537impl TransactionType {
538 pub fn is_explicit(&self) -> bool {
539 matches!(self, TransactionType::Explicit)
540 }
541
542 pub fn is_implicit(&self) -> bool {
543 matches!(self, TransactionType::Implicit)
544 }
545}
546
547#[derive(Debug)]
548pub struct CommitTransactionPlan {
549 pub transaction_type: TransactionType,
550}
551
552#[derive(Debug)]
553pub struct AbortTransactionPlan {
554 pub transaction_type: TransactionType,
555}
556
557#[derive(Debug)]
558pub struct CreateDatabasePlan {
559 pub name: String,
560 pub if_not_exists: bool,
561}
562
563#[derive(Debug)]
564pub struct CreateSchemaPlan {
565 pub database_spec: ResolvedDatabaseSpecifier,
566 pub schema_name: String,
567 pub if_not_exists: bool,
568}
569
570#[derive(Debug)]
571pub struct CreateRolePlan {
572 pub name: String,
573 pub attributes: RoleAttributesRaw,
574}
575
576#[derive(Debug, PartialEq, Eq, Clone)]
577pub struct CreateClusterPlan {
578 pub name: String,
579 pub variant: CreateClusterVariant,
580 pub workload_class: Option<String>,
581 pub if_not_exists: bool,
582}
583
584#[derive(Debug, PartialEq, Eq, Clone)]
585pub enum CreateClusterVariant {
586 Managed(CreateClusterManagedPlan),
587 Unmanaged(CreateClusterUnmanagedPlan),
588}
589
590#[derive(Debug, PartialEq, Eq, Clone)]
591pub struct CreateClusterUnmanagedPlan {
592 pub replicas: Vec<(String, ReplicaConfig)>,
593}
594
595#[derive(Debug, PartialEq, Eq, Clone)]
596pub struct CreateClusterManagedPlan {
597 pub replication_factor: u32,
598 pub size: String,
599 pub availability_zones: Vec<String>,
600 pub compute: ComputeReplicaConfig,
601 pub optimizer_feature_overrides: OptimizerFeatureOverrides,
602 pub schedule: ClusterSchedule,
603 pub auto_scaling_strategy: Option<AutoScalingStrategy>,
606}
607
608#[derive(Debug)]
609pub struct CreateClusterReplicaPlan {
610 pub cluster_id: ClusterId,
611 pub name: String,
612 pub config: ReplicaConfig,
613 pub if_not_exists: bool,
614}
615
616#[derive(
618 Clone,
619 Copy,
620 Debug,
621 Serialize,
622 Deserialize,
623 PartialOrd,
624 Ord,
625 PartialEq,
626 Eq
627)]
628pub struct ComputeReplicaIntrospectionConfig {
629 pub debugging: bool,
631 pub interval: Duration,
633}
634
635#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
636pub struct ComputeReplicaConfig {
637 pub introspection: Option<ComputeReplicaIntrospectionConfig>,
638 pub arrangement_compression: bool,
642}
643
644#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
645pub enum ReplicaConfig {
646 Unorchestrated {
647 storagectl_addrs: Vec<String>,
648 computectl_addrs: Vec<String>,
649 compute: ComputeReplicaConfig,
650 },
651 Orchestrated {
652 size: String,
653 availability_zone: Option<String>,
654 compute: ComputeReplicaConfig,
655 internal: bool,
656 billed_as: Option<String>,
657 },
658}
659
660#[derive(Clone, Debug, Deserialize, Serialize, PartialOrd, PartialEq, Eq, Ord)]
661pub enum ClusterSchedule {
662 Manual,
664 Refresh { hydration_time_estimate: Duration },
668}
669
670impl Default for ClusterSchedule {
671 fn default() -> Self {
672 ClusterSchedule::Manual
674 }
675}
676
677#[derive(Clone, Debug, Deserialize, Serialize, PartialOrd, PartialEq, Eq, Ord)]
682pub struct AutoScalingStrategy {
683 pub on_hydration: Option<OnHydration>,
684}
685
686#[derive(Clone, Debug, Deserialize, Serialize, PartialOrd, PartialEq, Eq, Ord)]
689pub struct OnHydration {
690 pub hydration_size: String,
691 pub linger_duration: Option<Duration>,
694}
695
696#[derive(Clone, Debug)]
697pub struct CreateSourcePlan {
698 pub name: QualifiedItemName,
699 pub source: Source,
700 pub if_not_exists: bool,
701 pub timeline: Timeline,
702 pub in_cluster: Option<ClusterId>,
704}
705
706#[derive(Clone, Debug, PartialEq, Eq)]
707pub struct SourceReferences {
708 pub updated_at: u64,
709 pub references: Vec<SourceReference>,
710}
711
712#[derive(Clone, Debug, PartialEq, Eq)]
715pub struct SourceReference {
716 pub name: String,
717 pub namespace: Option<String>,
718 pub columns: Vec<String>,
719}
720
721#[derive(Debug)]
723pub struct CreateSourcePlanBundle {
724 pub item_id: CatalogItemId,
726 pub global_id: GlobalId,
728 pub plan: CreateSourcePlan,
730 pub resolved_ids: ResolvedIds,
732 pub available_source_references: Option<SourceReferences>,
736}
737
738#[derive(Debug)]
739pub struct CreateConnectionPlan {
740 pub name: QualifiedItemName,
741 pub if_not_exists: bool,
742 pub connection: Connection,
743 pub validate: bool,
744}
745
746#[derive(Debug)]
747pub struct ValidateConnectionPlan {
748 pub id: CatalogItemId,
750 pub connection: mz_storage_types::connections::Connection<ReferencedConnection>,
752}
753
754#[derive(Debug)]
755pub struct CreateSecretPlan {
756 pub name: QualifiedItemName,
757 pub secret: Secret,
758 pub if_not_exists: bool,
759}
760
761#[derive(Debug)]
762pub struct CreateSinkPlan {
763 pub name: QualifiedItemName,
764 pub sink: Sink,
765 pub with_snapshot: bool,
766 pub if_not_exists: bool,
767 pub in_cluster: ClusterId,
768}
769
770#[derive(Debug)]
771pub struct CreateTablePlan {
772 pub name: QualifiedItemName,
773 pub table: Table,
774 pub if_not_exists: bool,
775}
776
777#[derive(Debug, Clone)]
778pub struct CreateViewPlan {
779 pub name: QualifiedItemName,
780 pub view: View,
781 pub replace: Option<CatalogItemId>,
783 pub drop_ids: Vec<CatalogItemId>,
785 pub if_not_exists: bool,
786 pub ambiguous_columns: bool,
789}
790
791#[derive(Debug, Clone)]
792pub struct CreateMaterializedViewPlan {
793 pub name: QualifiedItemName,
794 pub materialized_view: MaterializedView,
795 pub replace: Option<CatalogItemId>,
797 pub drop_ids: Vec<CatalogItemId>,
799 pub if_not_exists: bool,
800 pub ambiguous_columns: bool,
803}
804
805#[derive(Debug, Clone)]
806pub struct CreateNetworkPolicyPlan {
807 pub name: String,
808 pub rules: Vec<NetworkPolicyRule>,
809}
810
811#[derive(Debug, Clone)]
812pub struct AlterNetworkPolicyPlan {
813 pub id: NetworkPolicyId,
814 pub name: String,
815 pub rules: Vec<NetworkPolicyRule>,
816}
817
818#[derive(Debug, Clone)]
819pub struct CreateIndexPlan {
820 pub name: QualifiedItemName,
821 pub index: Index,
822 pub if_not_exists: bool,
823}
824
825#[derive(Debug, Clone)]
826pub struct CreateMetricSinkPlan {
827 pub name: QualifiedItemName,
828 pub metric_sink: MetricSink,
829 pub if_not_exists: bool,
830}
831
832#[derive(Debug)]
833pub struct CreateTypePlan {
834 pub name: QualifiedItemName,
835 pub typ: Type,
836}
837
838#[derive(Debug)]
839pub struct DropObjectsPlan {
840 pub referenced_ids: Vec<ObjectId>,
842 pub drop_ids: Vec<ObjectId>,
844 pub object_type: ObjectType,
847}
848
849#[derive(Debug)]
850pub struct DropOwnedPlan {
851 pub role_ids: Vec<RoleId>,
853 pub drop_ids: Vec<ObjectId>,
855 pub privilege_revokes: Vec<(SystemObjectId, MzAclItem)>,
857 pub default_privilege_revokes: Vec<(DefaultPrivilegeObject, DefaultPrivilegeAclItem)>,
859}
860
861#[derive(Debug)]
862pub struct ShowVariablePlan {
863 pub name: String,
864}
865
866#[derive(Debug)]
867pub struct InspectShardPlan {
868 pub id: GlobalId,
870}
871
872#[derive(Debug)]
873pub struct SetVariablePlan {
874 pub name: String,
875 pub value: VariableValue,
876 pub local: bool,
877}
878
879#[derive(Debug)]
880pub enum VariableValue {
881 Default,
882 Values(Vec<String>),
883}
884
885#[derive(Debug)]
886pub struct ResetVariablePlan {
887 pub name: String,
888}
889
890#[derive(Debug)]
891pub struct SetTransactionPlan {
892 pub local: bool,
893 pub modes: Vec<TransactionMode>,
894}
895
896#[derive(Clone, Debug)]
898pub struct SelectPlan {
899 pub select: Option<Box<SelectStatement<Aug>>>,
902 pub source: HirRelationExpr,
904 pub when: QueryWhen,
906 pub finishing: RowSetFinishing,
908 pub copy_to: Option<CopyFormat>,
910}
911
912impl SelectPlan {
913 pub fn immediate(rows: Vec<Row>, typ: SqlRelationType) -> Self {
914 let arity = typ.arity();
915 SelectPlan {
916 select: None,
917 source: HirRelationExpr::Constant { rows, typ },
918 when: QueryWhen::Immediately,
919 finishing: RowSetFinishing::trivial(arity),
920 copy_to: None,
921 }
922 }
923}
924
925#[derive(Debug, Clone)]
926pub enum SubscribeOutput {
927 Diffs,
928 WithinTimestampOrderBy {
929 order_by: Vec<ColumnOrder>,
931 },
932 EnvelopeUpsert {
933 order_by_keys: Vec<ColumnOrder>,
935 },
936 EnvelopeDebezium {
937 order_by_keys: Vec<ColumnOrder>,
939 },
940}
941
942impl SubscribeOutput {
943 pub fn row_order(&self) -> &[ColumnOrder] {
944 match self {
945 SubscribeOutput::Diffs => &[],
946 SubscribeOutput::WithinTimestampOrderBy { .. } => &[],
948 SubscribeOutput::EnvelopeUpsert { order_by_keys } => order_by_keys,
949 SubscribeOutput::EnvelopeDebezium { order_by_keys } => order_by_keys,
950 }
951 }
952}
953
954#[derive(Debug, Clone)]
955pub struct SubscribePlan {
956 pub from: SubscribeFrom,
957 pub with_snapshot: bool,
958 pub when: QueryWhen,
959 pub up_to: Option<Timestamp>,
960 pub copy_to: Option<CopyFormat>,
961 pub emit_progress: bool,
962 pub output: SubscribeOutput,
963}
964
965#[derive(Debug, Clone)]
966pub enum SubscribeFrom {
967 Id(GlobalId),
969 Query {
971 expr: HirRelationExpr,
972 desc: RelationDesc,
973 },
974}
975
976impl SubscribeFrom {
977 pub fn depends_on(&self) -> BTreeSet<GlobalId> {
978 match self {
979 SubscribeFrom::Id(id) => BTreeSet::from([*id]),
980 SubscribeFrom::Query { expr, .. } => expr.depends_on(),
981 }
982 }
983
984 pub fn contains_temporal(&self) -> bool {
985 match self {
986 SubscribeFrom::Id(_) => false,
987 SubscribeFrom::Query { expr, .. } => expr.contains_temporal(),
988 }
989 }
990}
991
992#[derive(Debug)]
993pub struct ShowCreatePlan {
994 pub id: ObjectId,
995 pub row: Row,
996}
997
998#[derive(Debug)]
999pub struct ShowColumnsPlan {
1000 pub id: CatalogItemId,
1001 pub select_plan: SelectPlan,
1002 pub new_resolved_ids: ResolvedIds,
1003}
1004
1005#[derive(Debug)]
1006pub struct CopyFromPlan {
1007 pub target_id: CatalogItemId,
1009 pub target_name: String,
1011 pub source: CopyFromSource,
1013 pub columns: Vec<ColumnIndex>,
1017 pub source_desc: RelationDesc,
1019 pub mfp: MapFilterProject,
1021 pub params: CopyFormatParams<'static>,
1023 pub filter: Option<CopyFromFilter>,
1025}
1026
1027#[derive(Debug)]
1028pub enum CopyFromSource {
1029 Stdin,
1031 Url(HirScalarExpr),
1035 AwsS3 {
1037 uri: HirScalarExpr,
1039 connection: AwsConnection,
1041 connection_id: CatalogItemId,
1043 },
1044}
1045
1046#[derive(Debug)]
1047pub enum CopyFromFilter {
1048 Files(Vec<String>),
1049 Pattern(String),
1050}
1051
1052#[derive(Debug, Clone)]
1057pub struct CopyToPlan {
1058 pub select_plan: SelectPlan,
1060 pub desc: RelationDesc,
1061 pub to: HirScalarExpr,
1063 pub connection: mz_storage_types::connections::Connection<ReferencedConnection>,
1064 pub connection_id: CatalogItemId,
1066 pub format: S3SinkFormat,
1067 pub max_file_size: u64,
1068}
1069
1070#[derive(Clone, Debug)]
1071pub struct ExplainPlanPlan {
1072 pub stage: ExplainStage,
1073 pub format: ExplainFormat,
1074 pub config: ExplainConfig,
1075 pub explainee: Explainee,
1076}
1077
1078#[derive(Clone, Debug)]
1080pub enum Explainee {
1081 View(CatalogItemId),
1083 MaterializedView(CatalogItemId),
1085 Index(CatalogItemId),
1087 ReplanView(CatalogItemId),
1089 ReplanMaterializedView(CatalogItemId),
1091 ReplanIndex(CatalogItemId),
1093 Statement(ExplaineeStatement),
1095}
1096
1097#[derive(Clone, Debug, EnumKind)]
1099#[enum_kind(ExplaineeStatementKind)]
1100pub enum ExplaineeStatement {
1101 Select {
1103 broken: bool,
1105 plan: plan::SelectPlan,
1106 desc: RelationDesc,
1107 },
1108 CreateView {
1110 broken: bool,
1112 plan: plan::CreateViewPlan,
1113 },
1114 CreateMaterializedView {
1116 broken: bool,
1118 plan: plan::CreateMaterializedViewPlan,
1119 },
1120 CreateIndex {
1122 broken: bool,
1124 plan: plan::CreateIndexPlan,
1125 },
1126 Subscribe {
1128 broken: bool,
1130 plan: plan::SubscribePlan,
1131 },
1132}
1133
1134impl ExplaineeStatement {
1135 pub fn depends_on(&self) -> BTreeSet<GlobalId> {
1136 match self {
1137 Self::Select { plan, .. } => plan.source.depends_on(),
1138 Self::CreateView { plan, .. } => plan.view.expr.depends_on(),
1139 Self::CreateMaterializedView { plan, .. } => plan.materialized_view.expr.depends_on(),
1140 Self::CreateIndex { plan, .. } => btreeset! {plan.index.on},
1141 Self::Subscribe { plan, .. } => plan.from.depends_on(),
1142 }
1143 }
1144
1145 pub fn broken(&self) -> bool {
1156 match self {
1157 Self::Select { broken, .. } => *broken,
1158 Self::CreateView { broken, .. } => *broken,
1159 Self::CreateMaterializedView { broken, .. } => *broken,
1160 Self::CreateIndex { broken, .. } => *broken,
1161 Self::Subscribe { broken, .. } => *broken,
1162 }
1163 }
1164}
1165
1166impl ExplaineeStatementKind {
1167 pub fn supports(&self, stage: &ExplainStage) -> bool {
1168 use ExplainStage::*;
1169 match self {
1170 Self::Select => true,
1171 Self::CreateView => ![GlobalPlan, PhysicalPlan].contains(stage),
1172 Self::CreateMaterializedView => true,
1173 Self::CreateIndex => ![RawPlan, DecorrelatedPlan, LocalPlan].contains(stage),
1174 Self::Subscribe => ![RawPlan, DecorrelatedPlan, LocalPlan].contains(stage),
1177 }
1178 }
1179}
1180
1181impl std::fmt::Display for ExplaineeStatementKind {
1182 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1183 match self {
1184 Self::Select => write!(f, "SELECT"),
1185 Self::CreateView => write!(f, "CREATE VIEW"),
1186 Self::CreateMaterializedView => write!(f, "CREATE MATERIALIZED VIEW"),
1187 Self::CreateIndex => write!(f, "CREATE INDEX"),
1188 Self::Subscribe => write!(f, "SUBSCRIBE"),
1189 }
1190 }
1191}
1192
1193#[derive(Clone, Debug)]
1194pub struct ExplainPushdownPlan {
1195 pub explainee: Explainee,
1196}
1197
1198#[derive(Clone, Debug)]
1199pub struct ExplainTimestampPlan {
1200 pub format: ExplainFormat,
1201 pub raw_plan: HirRelationExpr,
1202 pub when: QueryWhen,
1203}
1204
1205#[derive(Debug)]
1206pub struct ExplainSinkSchemaPlan {
1207 pub sink_from: GlobalId,
1208 pub json_schema: String,
1209}
1210
1211#[derive(Debug)]
1212pub struct SendDiffsPlan {
1213 pub id: CatalogItemId,
1214 pub updates: Vec<(Row, Diff)>,
1215 pub kind: MutationKind,
1216 pub returning: Vec<(Row, NonZeroUsize)>,
1217 pub max_result_size: u64,
1218}
1219
1220#[derive(Debug)]
1221pub struct InsertPlan {
1222 pub id: CatalogItemId,
1223 pub values: HirRelationExpr,
1224 pub returning: Vec<mz_expr::MirScalarExpr>,
1225}
1226
1227#[derive(Debug)]
1228pub struct ReadThenWritePlan {
1229 pub id: CatalogItemId,
1230 pub selection: HirRelationExpr,
1231 pub finishing: RowSetFinishing,
1232 pub assignments: BTreeMap<usize, mz_expr::MirScalarExpr>,
1233 pub kind: MutationKind,
1234 pub returning: Vec<mz_expr::MirScalarExpr>,
1235}
1236
1237#[derive(Debug)]
1239pub struct AlterNoopPlan {
1240 pub object_type: ObjectType,
1241}
1242
1243#[derive(Debug)]
1244pub struct AlterSetClusterPlan {
1245 pub id: CatalogItemId,
1246 pub set_cluster: ClusterId,
1247}
1248
1249#[derive(Debug)]
1250pub struct AlterRetainHistoryPlan {
1251 pub id: CatalogItemId,
1252 pub value: Option<Value>,
1253 pub window: CompactionWindow,
1254 pub object_type: ObjectType,
1255}
1256
1257#[derive(Debug)]
1258pub struct AlterSourceTimestampIntervalPlan {
1259 pub id: CatalogItemId,
1260 pub value: Option<Value>,
1261 pub interval: Duration,
1262}
1263
1264#[derive(Debug, Clone)]
1265
1266pub enum AlterOptionParameter<T = String> {
1267 Set(T),
1268 Reset,
1269 Unchanged,
1270}
1271
1272#[derive(Debug)]
1273pub enum AlterConnectionAction {
1274 RotateKeys,
1275 AlterOptions {
1276 set_options: BTreeMap<ConnectionOptionName, Option<WithOptionValue<Aug>>>,
1277 drop_options: BTreeSet<ConnectionOptionName>,
1278 validate: bool,
1279 },
1280}
1281
1282#[derive(Debug)]
1283pub struct AlterConnectionPlan {
1284 pub id: CatalogItemId,
1285 pub action: AlterConnectionAction,
1286}
1287
1288#[derive(Debug)]
1289pub enum AlterSourceAction {
1290 AddSubsourceExports {
1291 subsources: Vec<CreateSourcePlanBundle>,
1292 options: Vec<AlterSourceAddSubsourceOption<Aug>>,
1293 },
1294 RefreshReferences {
1295 references: SourceReferences,
1296 },
1297}
1298
1299#[derive(Debug)]
1300pub struct AlterSourcePlan {
1301 pub item_id: CatalogItemId,
1302 pub ingestion_id: GlobalId,
1303 pub action: AlterSourceAction,
1304}
1305
1306#[derive(Debug, Clone)]
1307pub struct AlterSinkPlan {
1308 pub item_id: CatalogItemId,
1309 pub global_id: GlobalId,
1310 pub sink: Sink,
1311 pub with_snapshot: bool,
1312 pub in_cluster: ClusterId,
1313 pub set_options: Vec<CreateSinkOption<Aug>>,
1318 pub reset_options: Vec<CreateSinkOptionName>,
1319}
1320
1321pub fn apply_sink_option_edits<T: mz_sql_parser::ast::AstInfo>(
1324 with_options: &mut Vec<CreateSinkOption<T>>,
1325 set_options: &[CreateSinkOption<T>],
1326 reset_options: &[CreateSinkOptionName],
1327) where
1328 CreateSinkOption<T>: Clone,
1329{
1330 with_options.retain(|o| {
1331 set_options.iter().all(|s| s.name != o.name) && !reset_options.contains(&o.name)
1332 });
1333 with_options.extend(set_options.iter().cloned());
1334}
1335
1336#[derive(Debug, Clone)]
1337pub struct AlterClusterPlan {
1338 pub id: ClusterId,
1339 pub name: String,
1340 pub options: PlanClusterOption,
1341 pub strategy: AlterClusterPlanStrategy,
1342}
1343
1344#[derive(Debug)]
1345pub struct AlterClusterRenamePlan {
1346 pub id: ClusterId,
1347 pub name: String,
1348 pub to_name: String,
1349}
1350
1351#[derive(Debug)]
1352pub struct AlterClusterReplicaRenamePlan {
1353 pub cluster_id: ClusterId,
1354 pub replica_id: ReplicaId,
1355 pub name: QualifiedReplica,
1356 pub to_name: String,
1357}
1358
1359#[derive(Debug)]
1360pub struct AlterItemRenamePlan {
1361 pub id: CatalogItemId,
1362 pub current_full_name: FullItemName,
1363 pub to_name: String,
1364 pub object_type: ObjectType,
1365}
1366
1367#[derive(Debug)]
1368pub struct AlterSchemaRenamePlan {
1369 pub cur_schema_spec: (ResolvedDatabaseSpecifier, SchemaSpecifier),
1370 pub new_schema_name: String,
1371}
1372
1373#[derive(Debug)]
1374pub struct AlterSchemaSwapPlan {
1375 pub schema_a_spec: (ResolvedDatabaseSpecifier, SchemaSpecifier),
1376 pub schema_a_name: String,
1377 pub schema_b_spec: (ResolvedDatabaseSpecifier, SchemaSpecifier),
1378 pub schema_b_name: String,
1379 pub name_temp: String,
1380}
1381
1382#[derive(Debug)]
1383pub struct AlterClusterSwapPlan {
1384 pub id_a: ClusterId,
1385 pub id_b: ClusterId,
1386 pub name_a: String,
1387 pub name_b: String,
1388 pub name_temp: String,
1389}
1390
1391#[derive(Debug)]
1392pub struct AlterSecretPlan {
1393 pub id: CatalogItemId,
1394 pub secret_as: MirScalarExpr,
1395}
1396
1397#[derive(Debug)]
1398pub struct AlterSystemSetPlan {
1399 pub name: String,
1400 pub value: VariableValue,
1401}
1402
1403#[derive(Debug)]
1404pub struct AlterSystemResetPlan {
1405 pub name: String,
1406}
1407
1408#[derive(Debug)]
1409pub struct AlterSystemResetAllPlan {}
1410
1411#[derive(Debug)]
1412pub struct AlterRolePlan {
1413 pub id: RoleId,
1414 pub name: String,
1415 pub option: PlannedAlterRoleOption,
1416}
1417
1418#[derive(Debug)]
1419pub struct AlterOwnerPlan {
1420 pub id: ObjectId,
1421 pub object_type: ObjectType,
1422 pub new_owner: RoleId,
1423}
1424
1425#[derive(Debug)]
1426pub struct AlterTablePlan {
1427 pub relation_id: CatalogItemId,
1428 pub column_name: ColumnName,
1429 pub column_type: SqlColumnType,
1430 pub raw_sql_type: RawDataType,
1431}
1432
1433#[derive(Debug, Clone)]
1434pub struct AlterMaterializedViewApplyReplacementPlan {
1435 pub id: CatalogItemId,
1436 pub replacement_id: CatalogItemId,
1437}
1438
1439#[derive(Debug)]
1440pub struct DeclarePlan {
1441 pub name: String,
1442 pub stmt: Statement<Raw>,
1443 pub sql: String,
1444 pub params: Params,
1445}
1446
1447#[derive(Debug)]
1448pub struct FetchPlan {
1449 pub name: String,
1450 pub count: Option<FetchDirection>,
1451 pub timeout: ExecuteTimeout,
1452}
1453
1454#[derive(Debug)]
1455pub struct ClosePlan {
1456 pub name: String,
1457}
1458
1459#[derive(Debug)]
1460pub struct PreparePlan {
1461 pub name: String,
1462 pub stmt: Statement<Raw>,
1463 pub sql: String,
1464 pub desc: StatementDesc,
1465}
1466
1467#[derive(Debug)]
1468pub struct ExecutePlan {
1469 pub name: String,
1470 pub params: Params,
1471}
1472
1473#[derive(Debug)]
1474pub struct DeallocatePlan {
1475 pub name: Option<String>,
1476}
1477
1478#[derive(Debug)]
1479pub struct RaisePlan {
1480 pub severity: NoticeSeverity,
1481}
1482
1483#[derive(Debug)]
1484pub struct GrantRolePlan {
1485 pub role_ids: Vec<RoleId>,
1487 pub member_ids: Vec<RoleId>,
1489 pub grantor_id: RoleId,
1491}
1492
1493#[derive(Debug)]
1494pub struct RevokeRolePlan {
1495 pub role_ids: Vec<RoleId>,
1497 pub member_ids: Vec<RoleId>,
1499 pub grantor_id: RoleId,
1501}
1502
1503#[derive(Debug)]
1504pub struct UpdatePrivilege {
1505 pub acl_mode: AclMode,
1507 pub target_id: SystemObjectId,
1509 pub grantor: RoleId,
1511 pub acl_from_all: bool,
1516}
1517
1518#[derive(Debug)]
1519pub struct GrantPrivilegesPlan {
1520 pub update_privileges: Vec<UpdatePrivilege>,
1522 pub grantees: Vec<RoleId>,
1524}
1525
1526#[derive(Debug)]
1527pub struct RevokePrivilegesPlan {
1528 pub update_privileges: Vec<UpdatePrivilege>,
1530 pub revokees: Vec<RoleId>,
1532}
1533#[derive(Debug)]
1534pub struct AlterDefaultPrivilegesPlan {
1535 pub privilege_objects: Vec<DefaultPrivilegeObject>,
1537 pub privilege_acl_items: Vec<DefaultPrivilegeAclItem>,
1539 pub is_grant: bool,
1541}
1542
1543#[derive(Debug)]
1544pub struct ReassignOwnedPlan {
1545 pub old_roles: Vec<RoleId>,
1547 pub new_role: RoleId,
1549 pub reassign_ids: Vec<ObjectId>,
1551}
1552
1553#[derive(Debug)]
1554pub struct CommentPlan {
1555 pub object_id: CommentObjectId,
1557 pub sub_component: Option<usize>,
1561 pub comment: Option<String>,
1563}
1564
1565#[derive(Clone, Debug)]
1566pub enum TableDataSource {
1567 TableWrites { defaults: Vec<Expr<Aug>> },
1569
1570 DataSource {
1573 desc: DataSourceDesc,
1574 timeline: Timeline,
1575 },
1576}
1577
1578#[derive(Clone, Debug)]
1579pub struct Table {
1580 pub create_sql: String,
1581 pub desc: VersionedRelationDesc,
1582 pub temporary: bool,
1583 pub compaction_window: Option<CompactionWindow>,
1584 pub data_source: TableDataSource,
1585}
1586
1587#[derive(Clone, Debug)]
1588pub struct Source {
1589 pub create_sql: String,
1590 pub data_source: DataSourceDesc,
1591 pub desc: RelationDesc,
1592 pub compaction_window: Option<CompactionWindow>,
1593}
1594
1595#[derive(Debug, Clone)]
1596pub enum DataSourceDesc {
1597 Ingestion(SourceDesc<ReferencedConnection>),
1599 OldSyntaxIngestion {
1601 desc: SourceDesc<ReferencedConnection>,
1602 progress_subsource: CatalogItemId,
1605 data_config: SourceExportDataConfig<ReferencedConnection>,
1606 details: SourceExportDetails,
1607 },
1608 IngestionExport {
1611 ingestion_id: CatalogItemId,
1612 external_reference: UnresolvedItemName,
1613 details: SourceExportDetails,
1614 data_config: SourceExportDataConfig<ReferencedConnection>,
1615 },
1616 Progress,
1618 Webhook {
1620 validate_using: Option<WebhookValidation>,
1621 body_format: WebhookBodyFormat,
1622 headers: WebhookHeaders,
1623 cluster_id: Option<StorageInstanceId>,
1625 },
1626}
1627
1628#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
1629pub struct WebhookValidation {
1630 pub expression: MirScalarExpr,
1632 pub relation_desc: RelationDesc,
1634 pub bodies: Vec<(usize, bool)>,
1636 pub headers: Vec<(usize, bool)>,
1638 pub secrets: Vec<WebhookValidationSecret>,
1640}
1641
1642impl WebhookValidation {
1643 const MAX_REDUCE_TIME: Duration = Duration::from_secs(60);
1644
1645 pub async fn reduce_expression(&mut self) -> Result<(), &'static str> {
1650 let WebhookValidation {
1651 expression,
1652 relation_desc,
1653 ..
1654 } = self;
1655
1656 let mut expression_ = expression.clone();
1658 let desc_ = relation_desc.clone();
1659 let reduce_task = mz_ore::task::spawn_blocking(
1660 || "webhook-validation-reduce",
1661 move || {
1662 let repr_col_types: Vec<ReprColumnType> = desc_
1663 .typ()
1664 .column_types
1665 .iter()
1666 .map(ReprColumnType::from)
1667 .collect();
1668 expression_.reduce(&repr_col_types);
1669 expression_
1670 },
1671 );
1672
1673 match tokio::time::timeout(Self::MAX_REDUCE_TIME, reduce_task).await {
1674 Ok(reduced_expr) => {
1675 *expression = reduced_expr;
1676 Ok(())
1677 }
1678 Err(_) => Err("timeout"),
1679 }
1680 }
1681}
1682
1683#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
1684pub struct WebhookHeaders {
1685 pub header_column: Option<WebhookHeaderFilters>,
1687 pub mapped_headers: BTreeMap<usize, (String, bool)>,
1689}
1690
1691impl WebhookHeaders {
1692 pub fn num_columns(&self) -> usize {
1694 let header_column = self.header_column.as_ref().map(|_| 1).unwrap_or(0);
1695 let mapped_headers = self.mapped_headers.len();
1696
1697 header_column + mapped_headers
1698 }
1699}
1700
1701#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
1702pub struct WebhookHeaderFilters {
1703 pub block: BTreeSet<String>,
1704 pub allow: BTreeSet<String>,
1705}
1706
1707#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Arbitrary)]
1708pub enum WebhookBodyFormat {
1709 Json { array: bool },
1710 Bytes,
1711 Text,
1712}
1713
1714impl From<WebhookBodyFormat> for SqlScalarType {
1715 fn from(value: WebhookBodyFormat) -> Self {
1716 match value {
1717 WebhookBodyFormat::Json { .. } => SqlScalarType::Jsonb,
1718 WebhookBodyFormat::Bytes => SqlScalarType::Bytes,
1719 WebhookBodyFormat::Text => SqlScalarType::String,
1720 }
1721 }
1722}
1723
1724#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
1725pub struct WebhookValidationSecret {
1726 pub id: CatalogItemId,
1728 pub column_idx: usize,
1730 pub use_bytes: bool,
1732}
1733
1734#[derive(Clone, Debug)]
1735pub struct Connection {
1736 pub create_sql: String,
1737 pub details: ConnectionDetails,
1738}
1739
1740#[derive(Clone, Debug, Serialize)]
1741pub enum ConnectionDetails {
1742 Kafka(KafkaConnection<ReferencedConnection>),
1743 Csr(CsrConnection<ReferencedConnection>),
1744 GlueSchemaRegistry(GlueSchemaRegistryConnection<ReferencedConnection>),
1745 Postgres(PostgresConnection<ReferencedConnection>),
1746 Ssh {
1747 connection: SshConnection,
1748 key_1: SshKey,
1749 key_2: SshKey,
1750 },
1751 Aws(AwsConnection),
1752 AwsPrivatelink(AwsPrivatelinkConnection),
1753 Gcp(GcpConnection),
1754 MySql(MySqlConnection<ReferencedConnection>),
1755 SqlServer(SqlServerConnectionDetails<ReferencedConnection>),
1756 IcebergCatalog(IcebergCatalogConnection<ReferencedConnection>),
1757}
1758
1759impl ConnectionDetails {
1760 pub fn to_connection(&self) -> mz_storage_types::connections::Connection<ReferencedConnection> {
1761 match self {
1762 ConnectionDetails::Kafka(c) => {
1763 mz_storage_types::connections::Connection::Kafka(c.clone())
1764 }
1765 ConnectionDetails::Csr(c) => mz_storage_types::connections::Connection::Csr(c.clone()),
1766 ConnectionDetails::GlueSchemaRegistry(c) => {
1767 mz_storage_types::connections::Connection::GlueSchemaRegistry(c.clone())
1768 }
1769 ConnectionDetails::Postgres(c) => {
1770 mz_storage_types::connections::Connection::Postgres(c.clone())
1771 }
1772 ConnectionDetails::Ssh { connection, .. } => {
1773 mz_storage_types::connections::Connection::Ssh(connection.clone())
1774 }
1775 ConnectionDetails::Aws(c) => mz_storage_types::connections::Connection::Aws(c.clone()),
1776 ConnectionDetails::AwsPrivatelink(c) => {
1777 mz_storage_types::connections::Connection::AwsPrivatelink(c.clone())
1778 }
1779 ConnectionDetails::Gcp(c) => mz_storage_types::connections::Connection::Gcp(c.clone()),
1780 ConnectionDetails::MySql(c) => {
1781 mz_storage_types::connections::Connection::MySql(c.clone())
1782 }
1783 ConnectionDetails::SqlServer(c) => {
1784 mz_storage_types::connections::Connection::SqlServer(c.clone())
1785 }
1786 ConnectionDetails::IcebergCatalog(c) => {
1787 mz_storage_types::connections::Connection::IcebergCatalog(c.clone())
1788 }
1789 }
1790 }
1791
1792 pub fn secret_content_guards(
1804 &self,
1805 ) -> Vec<(CatalogItemId, fn(&str) -> Result<(), anyhow::Error>)> {
1806 match self {
1807 ConnectionDetails::Gcp(gcp) => vec![(
1810 gcp.credentials_json,
1811 GcpServiceAccountKeyTokenUri::validate_json,
1812 )],
1813 _ => vec![],
1814 }
1815 }
1816}
1817
1818#[derive(Debug, Clone, Serialize, PartialEq, Eq, Ord, PartialOrd, Hash)]
1819pub struct NetworkPolicyRule {
1820 pub name: String,
1821 pub action: NetworkPolicyRuleAction,
1822 pub address: PolicyAddress,
1823 pub direction: NetworkPolicyRuleDirection,
1824}
1825
1826#[derive(
1827 Debug,
1828 Clone,
1829 Serialize,
1830 Deserialize,
1831 PartialEq,
1832 Eq,
1833 Ord,
1834 PartialOrd,
1835 Hash
1836)]
1837pub enum NetworkPolicyRuleAction {
1838 Allow,
1839}
1840
1841impl std::fmt::Display for NetworkPolicyRuleAction {
1842 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1843 match self {
1844 Self::Allow => write!(f, "allow"),
1845 }
1846 }
1847}
1848impl TryFrom<&str> for NetworkPolicyRuleAction {
1849 type Error = PlanError;
1850 fn try_from(value: &str) -> Result<Self, Self::Error> {
1851 match value.to_uppercase().as_str() {
1852 "ALLOW" => Ok(Self::Allow),
1853 _ => Err(PlanError::Unstructured(
1854 "Allow is the only valid option".into(),
1855 )),
1856 }
1857 }
1858}
1859
1860#[derive(Debug, Clone, Serialize, PartialEq, Eq, Ord, PartialOrd, Hash)]
1861pub enum NetworkPolicyRuleDirection {
1862 Ingress,
1863}
1864impl std::fmt::Display for NetworkPolicyRuleDirection {
1865 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1866 match self {
1867 Self::Ingress => write!(f, "ingress"),
1868 }
1869 }
1870}
1871impl TryFrom<&str> for NetworkPolicyRuleDirection {
1872 type Error = PlanError;
1873 fn try_from(value: &str) -> Result<Self, Self::Error> {
1874 match value.to_uppercase().as_str() {
1875 "INGRESS" => Ok(Self::Ingress),
1876 _ => Err(PlanError::Unstructured(
1877 "Ingress is the only valid option".into(),
1878 )),
1879 }
1880 }
1881}
1882
1883#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
1884pub struct PolicyAddress(pub IpNet);
1885impl std::fmt::Display for PolicyAddress {
1886 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1887 write!(f, "{}", self.0)
1888 }
1889}
1890impl From<String> for PolicyAddress {
1891 fn from(value: String) -> Self {
1892 Self(IpNet::from_str(&value).expect("expected value to be IpNet"))
1893 }
1894}
1895impl TryFrom<&str> for PolicyAddress {
1896 type Error = PlanError;
1897 fn try_from(value: &str) -> Result<Self, Self::Error> {
1898 let net = IpNet::from_str(value)
1899 .map_err(|_| PlanError::Unstructured("Value must be valid IPV4 or IPV6 CIDR".into()))?;
1900 Ok(Self(net))
1901 }
1902}
1903
1904impl Serialize for PolicyAddress {
1905 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1906 where
1907 S: serde::Serializer,
1908 {
1909 serializer.serialize_str(&format!("{}", self.0))
1910 }
1911}
1912
1913#[derive(Clone, Debug, Serialize)]
1914pub enum SshKey {
1915 PublicOnly(String),
1916 Both(SshKeyPair),
1917}
1918
1919impl SshKey {
1920 pub fn as_key_pair(&self) -> Option<&SshKeyPair> {
1921 match self {
1922 SshKey::PublicOnly(_) => None,
1923 SshKey::Both(key_pair) => Some(key_pair),
1924 }
1925 }
1926
1927 pub fn public_key(&self) -> String {
1928 match self {
1929 SshKey::PublicOnly(s) => s.into(),
1930 SshKey::Both(p) => p.ssh_public_key(),
1931 }
1932 }
1933}
1934
1935#[derive(Clone, Debug)]
1936pub struct Secret {
1937 pub create_sql: String,
1938 pub secret_as: MirScalarExpr,
1939}
1940
1941#[derive(Clone, Debug)]
1942pub struct Sink {
1943 pub create_sql: String,
1945 pub from: GlobalId,
1947 pub connection: StorageSinkConnection<ReferencedConnection>,
1949 pub envelope: SinkEnvelope,
1951 pub version: u64,
1952 pub commit_interval: Option<Duration>,
1953}
1954
1955#[derive(Clone, Debug)]
1956pub struct View {
1957 pub create_sql: String,
1959 pub expr: HirRelationExpr,
1961 pub dependencies: DependencyIds,
1963 pub column_names: Vec<ColumnName>,
1965 pub temporary: bool,
1967}
1968
1969#[derive(Clone, Debug)]
1970pub struct MaterializedView {
1971 pub create_sql: String,
1973 pub expr: HirRelationExpr,
1975 pub dependencies: DependencyIds,
1977 pub column_names: Vec<ColumnName>,
1979 pub replacement_target: Option<CatalogItemId>,
1980 pub cluster_id: ClusterId,
1982 pub target_replica: Option<ReplicaId>,
1984 pub non_null_assertions: Vec<usize>,
1985 pub compaction_window: Option<CompactionWindow>,
1986 pub refresh_schedule: Option<RefreshSchedule>,
1987 pub as_of: Option<Timestamp>,
1988}
1989
1990#[derive(Clone, Debug)]
1991pub struct Index {
1992 pub create_sql: String,
1994 pub on: GlobalId,
1996 pub keys: Vec<mz_expr::MirScalarExpr>,
1997 pub compaction_window: Option<CompactionWindow>,
1998 pub cluster_id: ClusterId,
1999}
2000
2001#[derive(Clone, Debug)]
2002pub struct MetricSink {
2003 pub create_sql: String,
2005 pub from: GlobalId,
2007 pub cluster_id: ClusterId,
2008 pub prefix: String,
2011}
2012
2013#[derive(Clone, Debug)]
2014pub struct Type {
2015 pub create_sql: String,
2016 pub inner: CatalogType<IdReference>,
2017}
2018
2019#[derive(Deserialize, Clone, Debug, PartialEq)]
2021pub enum QueryWhen {
2022 Immediately,
2025 FreshestTableWrite,
2028 AtTimestamp(Timestamp),
2033 AtLeastTimestamp(Timestamp),
2036}
2037
2038impl QueryWhen {
2039 pub fn advance_to_timestamp(&self) -> Option<Timestamp> {
2041 match self {
2042 QueryWhen::AtTimestamp(t) | QueryWhen::AtLeastTimestamp(t) => Some(t.clone()),
2043 QueryWhen::Immediately | QueryWhen::FreshestTableWrite => None,
2044 }
2045 }
2046 pub fn constrains_upper(&self) -> bool {
2050 match self {
2051 QueryWhen::AtTimestamp(_) => true,
2052 QueryWhen::AtLeastTimestamp(_)
2053 | QueryWhen::Immediately
2054 | QueryWhen::FreshestTableWrite => false,
2055 }
2056 }
2057 pub fn advance_to_since(&self) -> bool {
2059 match self {
2060 QueryWhen::Immediately
2061 | QueryWhen::AtLeastTimestamp(_)
2062 | QueryWhen::FreshestTableWrite => true,
2063 QueryWhen::AtTimestamp(_) => false,
2064 }
2065 }
2066 pub fn can_advance_to_upper(&self) -> bool {
2068 match self {
2069 QueryWhen::Immediately => true,
2070 QueryWhen::FreshestTableWrite
2071 | QueryWhen::AtTimestamp(_)
2072 | QueryWhen::AtLeastTimestamp(_) => false,
2073 }
2074 }
2075
2076 pub fn can_advance_to_timeline_ts(&self) -> bool {
2078 match self {
2079 QueryWhen::Immediately | QueryWhen::FreshestTableWrite => true,
2080 QueryWhen::AtTimestamp(_) | QueryWhen::AtLeastTimestamp(_) => false,
2081 }
2082 }
2083 pub fn must_advance_to_timeline_ts(&self) -> bool {
2085 match self {
2086 QueryWhen::FreshestTableWrite => true,
2087 QueryWhen::Immediately | QueryWhen::AtLeastTimestamp(_) | QueryWhen::AtTimestamp(_) => {
2088 false
2089 }
2090 }
2091 }
2092 pub fn is_transactional(&self) -> bool {
2094 match self {
2095 QueryWhen::Immediately | QueryWhen::FreshestTableWrite => true,
2096 QueryWhen::AtLeastTimestamp(_) | QueryWhen::AtTimestamp(_) => false,
2097 }
2098 }
2099}
2100
2101#[derive(Debug, Copy, Clone)]
2102pub enum MutationKind {
2103 Insert,
2104 Update,
2105 Delete,
2106}
2107
2108#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
2109pub enum CopyFormat {
2110 Text,
2111 Csv,
2112 Binary,
2113 Parquet,
2114}
2115
2116#[derive(Debug, Copy, Clone)]
2117pub enum ExecuteTimeout {
2118 None,
2119 Seconds(f64),
2120 WaitOnce,
2121}
2122
2123#[derive(Clone, Debug)]
2124pub enum IndexOption {
2125 RetainHistory(CompactionWindow),
2127}
2128
2129#[derive(Clone, Debug)]
2130pub enum TableOption {
2131 RetainHistory(CompactionWindow),
2133}
2134
2135#[derive(Clone, Debug)]
2136pub struct PlanClusterOption {
2137 pub availability_zones: AlterOptionParameter<Vec<String>>,
2138 pub introspection_debugging: AlterOptionParameter<bool>,
2139 pub introspection_interval: AlterOptionParameter<OptionalDuration>,
2140 pub arrangement_compression: AlterOptionParameter<bool>,
2141 pub managed: AlterOptionParameter<bool>,
2142 pub replicas: AlterOptionParameter<Vec<(String, ReplicaConfig)>>,
2143 pub replication_factor: AlterOptionParameter<u32>,
2144 pub size: AlterOptionParameter,
2145 pub schedule: AlterOptionParameter<ClusterSchedule>,
2146 pub workload_class: AlterOptionParameter<Option<String>>,
2147 pub auto_scaling_strategy: AlterOptionParameter<Option<AutoScalingStrategy>>,
2150}
2151
2152impl Default for PlanClusterOption {
2153 fn default() -> Self {
2154 Self {
2155 availability_zones: AlterOptionParameter::Unchanged,
2156 introspection_debugging: AlterOptionParameter::Unchanged,
2157 introspection_interval: AlterOptionParameter::Unchanged,
2158 arrangement_compression: AlterOptionParameter::Unchanged,
2159 managed: AlterOptionParameter::Unchanged,
2160 replicas: AlterOptionParameter::Unchanged,
2161 replication_factor: AlterOptionParameter::Unchanged,
2162 size: AlterOptionParameter::Unchanged,
2163 schedule: AlterOptionParameter::Unchanged,
2164 workload_class: AlterOptionParameter::Unchanged,
2165 auto_scaling_strategy: AlterOptionParameter::Unchanged,
2166 }
2167 }
2168}
2169
2170#[derive(Clone, Debug, PartialEq, Eq)]
2171pub enum AlterClusterPlanStrategy {
2172 None,
2173 For(Duration),
2174 UntilReady {
2175 on_timeout: Option<OnTimeoutAction>,
2178 timeout: Duration,
2179 },
2180}
2181
2182#[derive(
2183 Clone,
2184 Copy,
2185 Debug,
2186 Deserialize,
2187 Serialize,
2188 PartialOrd,
2189 PartialEq,
2190 Eq,
2191 Ord
2192)]
2193pub enum OnTimeoutAction {
2194 Commit,
2196 Rollback,
2198}
2199
2200impl TryFrom<&str> for OnTimeoutAction {
2201 type Error = PlanError;
2202 fn try_from(value: &str) -> Result<Self, Self::Error> {
2203 match value.to_uppercase().as_str() {
2204 "COMMIT" => Ok(Self::Commit),
2205 "ROLLBACK" => Ok(Self::Rollback),
2206 _ => Err(PlanError::Unstructured(
2207 "Valid options are COMMIT, ROLLBACK".into(),
2208 )),
2209 }
2210 }
2211}
2212
2213impl AlterClusterPlanStrategy {
2214 pub fn is_none(&self) -> bool {
2215 matches!(self, Self::None)
2216 }
2217 pub fn is_some(&self) -> bool {
2218 !matches!(self, Self::None)
2219 }
2220}
2221
2222impl TryFrom<ClusterAlterOptionExtracted> for AlterClusterPlanStrategy {
2223 type Error = PlanError;
2224
2225 fn try_from(value: ClusterAlterOptionExtracted) -> Result<Self, Self::Error> {
2226 Ok(match value.wait {
2227 Some(ClusterAlterOptionValue::For(d)) => Self::For(Duration::try_from_value(d)?),
2228 Some(ClusterAlterOptionValue::UntilReady(options)) => {
2229 let extracted = ClusterAlterUntilReadyOptionExtracted::try_from(options)?;
2230 Self::UntilReady {
2231 timeout: match extracted.timeout {
2232 Some(d) => d,
2233 None => Err(PlanError::UntilReadyTimeoutRequired)?,
2234 },
2235 on_timeout: match extracted.on_timeout {
2236 Some(v) => Some(OnTimeoutAction::try_from(v.as_str()).map_err(|e| {
2237 PlanError::InvalidOptionValue {
2238 option_name: "ON TIMEOUT".into(),
2239 err: Box::new(e),
2240 }
2241 })?),
2242 None => None,
2243 },
2244 }
2245 }
2246 None => Self::None,
2247 })
2248 }
2249}
2250
2251#[derive(Debug, Clone)]
2253pub struct Params {
2254 pub datums: Row,
2256 pub execute_types: Vec<SqlScalarType>,
2258 pub expected_types: Vec<SqlScalarType>,
2260}
2261
2262impl Params {
2263 pub fn empty() -> Params {
2265 Params {
2266 datums: Row::pack_slice(&[]),
2267 execute_types: vec![],
2268 expected_types: vec![],
2269 }
2270 }
2271}
2272
2273#[derive(
2275 Ord,
2276 PartialOrd,
2277 Clone,
2278 Debug,
2279 Eq,
2280 PartialEq,
2281 Serialize,
2282 Deserialize,
2283 Hash,
2284 Copy
2285)]
2286pub struct PlanContext {
2287 pub wall_time: DateTime<Utc>,
2288 pub ignore_if_exists_errors: bool,
2289}
2290
2291impl PlanContext {
2292 pub fn new(wall_time: DateTime<Utc>) -> Self {
2293 Self {
2294 wall_time,
2295 ignore_if_exists_errors: false,
2296 }
2297 }
2298
2299 pub fn zero() -> Self {
2303 PlanContext {
2304 wall_time: now::to_datetime(NOW_ZERO()),
2305 ignore_if_exists_errors: false,
2306 }
2307 }
2308
2309 pub fn with_ignore_if_exists_errors(mut self, value: bool) -> Self {
2310 self.ignore_if_exists_errors = value;
2311 self
2312 }
2313}