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