1use std::collections::BTreeMap;
22use std::fmt;
23
24use enum_kinds::EnumKind;
25use serde::{Deserialize, Serialize};
26use smallvec::{SmallVec, smallvec};
27
28use crate::ast::display::{self, AstDisplay, AstFormatter, WithOptionName};
29use crate::ast::{
30 AstInfo, ColumnDef, ConnectionOption, ConnectionOptionName, CreateConnectionOption,
31 CreateConnectionType, CreateSinkConnection, CreateSourceConnection, CreateSourceOption,
32 CreateSourceOptionName, DeferredItemName, Expr, Format, FormatSpecifier, IcebergSinkMode,
33 Ident, IntervalValue, KeyConstraint, MaterializedViewOption, Query, SelectItem, SinkEnvelope,
34 SourceEnvelope, SourceIncludeMetadata, SubscribeOutput, TableAlias, TableConstraint,
35 TableWithJoins, UnresolvedDatabaseName, UnresolvedItemName, UnresolvedObjectName,
36 UnresolvedSchemaName, Value,
37};
38
39#[allow(clippy::large_enum_variant)]
41#[derive(Debug, Clone, PartialEq, Eq, Hash, EnumKind)]
42#[enum_kind(StatementKind, derive(Serialize, Deserialize))]
43pub enum Statement<T: AstInfo> {
44 Select(SelectStatement<T>),
45 Insert(InsertStatement<T>),
46 Copy(CopyStatement<T>),
47 Update(UpdateStatement<T>),
48 Delete(DeleteStatement<T>),
49 CreateConnection(CreateConnectionStatement<T>),
50 CreateDatabase(CreateDatabaseStatement),
51 CreateSchema(CreateSchemaStatement),
52 CreateWebhookSource(CreateWebhookSourceStatement<T>),
53 CreateSource(CreateSourceStatement<T>),
54 CreateSubsource(CreateSubsourceStatement<T>),
55 CreateSink(CreateSinkStatement<T>),
56 CreateMetricSink(CreateMetricSinkStatement<T>),
57 CreateView(CreateViewStatement<T>),
58 CreateMaterializedView(CreateMaterializedViewStatement<T>),
59 CreateTable(CreateTableStatement<T>),
60 CreateTableFromSource(CreateTableFromSourceStatement<T>),
61 CreateIndex(CreateIndexStatement<T>),
62 CreateType(CreateTypeStatement<T>),
63 CreateRole(CreateRoleStatement),
64 CreateCluster(CreateClusterStatement<T>),
65 CreateClusterReplica(CreateClusterReplicaStatement<T>),
66 CreateSecret(CreateSecretStatement<T>),
67 CreateNetworkPolicy(CreateNetworkPolicyStatement<T>),
68 AlterCluster(AlterClusterStatement<T>),
69 AlterOwner(AlterOwnerStatement<T>),
70 AlterObjectRename(AlterObjectRenameStatement),
71 AlterObjectSwap(AlterObjectSwapStatement),
72 AlterRetainHistory(AlterRetainHistoryStatement<T>),
73 AlterIndex(AlterIndexStatement<T>),
74 AlterSecret(AlterSecretStatement<T>),
75 AlterSetCluster(AlterSetClusterStatement<T>),
76 AlterSink(AlterSinkStatement<T>),
77 AlterSource(AlterSourceStatement<T>),
78 AlterSystemSet(AlterSystemSetStatement),
79 AlterSystemReset(AlterSystemResetStatement),
80 AlterSystemResetAll(AlterSystemResetAllStatement),
81 AlterConnection(AlterConnectionStatement<T>),
82 AlterNetworkPolicy(AlterNetworkPolicyStatement<T>),
83 AlterRole(AlterRoleStatement<T>),
84 AlterTableAddColumn(AlterTableAddColumnStatement<T>),
85 AlterMaterializedViewApplyReplacement(AlterMaterializedViewApplyReplacementStatement),
86 Discard(DiscardStatement),
87 DropObjects(DropObjectsStatement),
88 DropOwned(DropOwnedStatement<T>),
89 SetVariable(SetVariableStatement),
90 ResetVariable(ResetVariableStatement),
91 Show(ShowStatement<T>),
92 StartTransaction(StartTransactionStatement),
93 SetTransaction(SetTransactionStatement),
94 Commit(CommitStatement),
95 Rollback(RollbackStatement),
96 Subscribe(SubscribeStatement<T>),
97 ExplainPlan(ExplainPlanStatement<T>),
98 ExplainPushdown(ExplainPushdownStatement<T>),
99 ExplainTimestamp(ExplainTimestampStatement<T>),
100 ExplainSinkSchema(ExplainSinkSchemaStatement<T>),
101 ExplainAnalyzeObject(ExplainAnalyzeObjectStatement<T>),
102 ExplainAnalyzeCluster(ExplainAnalyzeClusterStatement),
103 Declare(DeclareStatement<T>),
104 Fetch(FetchStatement<T>),
105 Close(CloseStatement),
106 Prepare(PrepareStatement<T>),
107 Execute(ExecuteStatement<T>),
108 ExecuteUnitTest(ExecuteUnitTestStatement<T>),
109 Deallocate(DeallocateStatement),
110 Raise(RaiseStatement),
111 GrantRole(GrantRoleStatement<T>),
112 RevokeRole(RevokeRoleStatement<T>),
113 GrantPrivileges(GrantPrivilegesStatement<T>),
114 RevokePrivileges(RevokePrivilegesStatement<T>),
115 AlterDefaultPrivileges(AlterDefaultPrivilegesStatement<T>),
116 ReassignOwned(ReassignOwnedStatement<T>),
117 ValidateConnection(ValidateConnectionStatement<T>),
118 Comment(CommentStatement<T>),
119}
120
121impl<T: AstInfo> AstDisplay for Statement<T> {
122 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
123 match self {
124 Statement::Select(stmt) => f.write_node(stmt),
125 Statement::Insert(stmt) => f.write_node(stmt),
126 Statement::Copy(stmt) => f.write_node(stmt),
127 Statement::Update(stmt) => f.write_node(stmt),
128 Statement::Delete(stmt) => f.write_node(stmt),
129 Statement::CreateConnection(stmt) => f.write_node(stmt),
130 Statement::CreateDatabase(stmt) => f.write_node(stmt),
131 Statement::CreateSchema(stmt) => f.write_node(stmt),
132 Statement::CreateWebhookSource(stmt) => f.write_node(stmt),
133 Statement::CreateSource(stmt) => f.write_node(stmt),
134 Statement::CreateSubsource(stmt) => f.write_node(stmt),
135 Statement::CreateSink(stmt) => f.write_node(stmt),
136 Statement::CreateMetricSink(stmt) => f.write_node(stmt),
137 Statement::CreateView(stmt) => f.write_node(stmt),
138 Statement::CreateMaterializedView(stmt) => f.write_node(stmt),
139 Statement::CreateTable(stmt) => f.write_node(stmt),
140 Statement::CreateTableFromSource(stmt) => f.write_node(stmt),
141 Statement::CreateIndex(stmt) => f.write_node(stmt),
142 Statement::CreateRole(stmt) => f.write_node(stmt),
143 Statement::CreateSecret(stmt) => f.write_node(stmt),
144 Statement::CreateType(stmt) => f.write_node(stmt),
145 Statement::CreateCluster(stmt) => f.write_node(stmt),
146 Statement::CreateClusterReplica(stmt) => f.write_node(stmt),
147 Statement::CreateNetworkPolicy(stmt) => f.write_node(stmt),
148 Statement::AlterCluster(stmt) => f.write_node(stmt),
149 Statement::AlterNetworkPolicy(stmt) => f.write_node(stmt),
150 Statement::AlterOwner(stmt) => f.write_node(stmt),
151 Statement::AlterObjectRename(stmt) => f.write_node(stmt),
152 Statement::AlterRetainHistory(stmt) => f.write_node(stmt),
153 Statement::AlterObjectSwap(stmt) => f.write_node(stmt),
154 Statement::AlterIndex(stmt) => f.write_node(stmt),
155 Statement::AlterSetCluster(stmt) => f.write_node(stmt),
156 Statement::AlterSecret(stmt) => f.write_node(stmt),
157 Statement::AlterSink(stmt) => f.write_node(stmt),
158 Statement::AlterSource(stmt) => f.write_node(stmt),
159 Statement::AlterSystemSet(stmt) => f.write_node(stmt),
160 Statement::AlterSystemReset(stmt) => f.write_node(stmt),
161 Statement::AlterSystemResetAll(stmt) => f.write_node(stmt),
162 Statement::AlterConnection(stmt) => f.write_node(stmt),
163 Statement::AlterRole(stmt) => f.write_node(stmt),
164 Statement::AlterTableAddColumn(stmt) => f.write_node(stmt),
165 Statement::AlterMaterializedViewApplyReplacement(stmt) => f.write_node(stmt),
166 Statement::Discard(stmt) => f.write_node(stmt),
167 Statement::DropObjects(stmt) => f.write_node(stmt),
168 Statement::DropOwned(stmt) => f.write_node(stmt),
169 Statement::SetVariable(stmt) => f.write_node(stmt),
170 Statement::ResetVariable(stmt) => f.write_node(stmt),
171 Statement::Show(stmt) => f.write_node(stmt),
172 Statement::StartTransaction(stmt) => f.write_node(stmt),
173 Statement::SetTransaction(stmt) => f.write_node(stmt),
174 Statement::Commit(stmt) => f.write_node(stmt),
175 Statement::Rollback(stmt) => f.write_node(stmt),
176 Statement::Subscribe(stmt) => f.write_node(stmt),
177 Statement::ExplainPlan(stmt) => f.write_node(stmt),
178 Statement::ExplainPushdown(stmt) => f.write_node(stmt),
179 Statement::ExplainAnalyzeObject(stmt) => f.write_node(stmt),
180 Statement::ExplainAnalyzeCluster(stmt) => f.write_node(stmt),
181 Statement::ExplainTimestamp(stmt) => f.write_node(stmt),
182 Statement::ExplainSinkSchema(stmt) => f.write_node(stmt),
183 Statement::Declare(stmt) => f.write_node(stmt),
184 Statement::Close(stmt) => f.write_node(stmt),
185 Statement::Fetch(stmt) => f.write_node(stmt),
186 Statement::Prepare(stmt) => f.write_node(stmt),
187 Statement::Execute(stmt) => f.write_node(stmt),
188 Statement::ExecuteUnitTest(stmt) => f.write_node(stmt),
189 Statement::Deallocate(stmt) => f.write_node(stmt),
190 Statement::Raise(stmt) => f.write_node(stmt),
191 Statement::GrantRole(stmt) => f.write_node(stmt),
192 Statement::RevokeRole(stmt) => f.write_node(stmt),
193 Statement::GrantPrivileges(stmt) => f.write_node(stmt),
194 Statement::RevokePrivileges(stmt) => f.write_node(stmt),
195 Statement::AlterDefaultPrivileges(stmt) => f.write_node(stmt),
196 Statement::ReassignOwned(stmt) => f.write_node(stmt),
197 Statement::ValidateConnection(stmt) => f.write_node(stmt),
198 Statement::Comment(stmt) => f.write_node(stmt),
199 }
200 }
201}
202impl_display_t!(Statement);
203
204impl StatementKind {
205 pub fn is_explain(&self) -> bool {
207 match self {
208 Self::ExplainPlan
209 | Self::ExplainPushdown
210 | Self::ExplainTimestamp
211 | Self::ExplainSinkSchema
212 | Self::ExplainAnalyzeObject
213 | Self::ExplainAnalyzeCluster => true,
214 Self::Select
215 | Self::Insert
216 | Self::Copy
217 | Self::Update
218 | Self::Delete
219 | Self::CreateConnection
220 | Self::CreateDatabase
221 | Self::CreateSchema
222 | Self::CreateWebhookSource
223 | Self::CreateSource
224 | Self::CreateSubsource
225 | Self::CreateSink
226 | Self::CreateMetricSink
227 | Self::CreateView
228 | Self::CreateMaterializedView
229 | Self::CreateTable
230 | Self::CreateTableFromSource
231 | Self::CreateIndex
232 | Self::CreateType
233 | Self::CreateRole
234 | Self::CreateCluster
235 | Self::CreateClusterReplica
236 | Self::CreateSecret
237 | Self::CreateNetworkPolicy
238 | Self::AlterCluster
239 | Self::AlterOwner
240 | Self::AlterObjectRename
241 | Self::AlterObjectSwap
242 | Self::AlterRetainHistory
243 | Self::AlterIndex
244 | Self::AlterSecret
245 | Self::AlterSetCluster
246 | Self::AlterSink
247 | Self::AlterSource
248 | Self::AlterSystemSet
249 | Self::AlterSystemReset
250 | Self::AlterSystemResetAll
251 | Self::AlterConnection
252 | Self::AlterNetworkPolicy
253 | Self::AlterRole
254 | Self::AlterTableAddColumn
255 | Self::AlterMaterializedViewApplyReplacement
256 | Self::Discard
257 | Self::DropObjects
258 | Self::DropOwned
259 | Self::SetVariable
260 | Self::ResetVariable
261 | Self::Show
262 | Self::StartTransaction
263 | Self::SetTransaction
264 | Self::Commit
265 | Self::Rollback
266 | Self::Subscribe
267 | Self::Declare
268 | Self::Fetch
269 | Self::Close
270 | Self::Prepare
271 | Self::Execute
272 | Self::ExecuteUnitTest
273 | Self::Deallocate
274 | Self::Raise
275 | Self::GrantRole
276 | Self::RevokeRole
277 | Self::GrantPrivileges
278 | Self::RevokePrivileges
279 | Self::AlterDefaultPrivileges
280 | Self::ReassignOwned
281 | Self::ValidateConnection
282 | Self::Comment => false,
283 }
284 }
285
286 pub fn is_secret(&self) -> bool {
291 matches!(
292 self,
293 StatementKind::CreateSecret | StatementKind::AlterSecret
294 )
295 }
296
297 pub fn is_sensitive(&self) -> bool {
302 self.is_secret()
303 || matches!(
304 self,
305 StatementKind::Insert | StatementKind::Update | StatementKind::Execute
306 )
307 }
308}
309
310pub fn statement_kind_label_value(kind: StatementKind) -> &'static str {
312 match kind {
313 StatementKind::Select => "select",
314 StatementKind::Insert => "insert",
315 StatementKind::Copy => "copy",
316 StatementKind::Update => "update",
317 StatementKind::Delete => "delete",
318 StatementKind::CreateConnection => "create_connection",
319 StatementKind::CreateDatabase => "create_database",
320 StatementKind::CreateSchema => "create_schema",
321 StatementKind::CreateWebhookSource => "create_webhook",
322 StatementKind::CreateSource => "create_source",
323 StatementKind::CreateSubsource => "create_subsource",
324 StatementKind::CreateSink => "create_sink",
325 StatementKind::CreateMetricSink => "create_metric_sink",
326 StatementKind::CreateView => "create_view",
327 StatementKind::CreateMaterializedView => "create_materialized_view",
328 StatementKind::CreateTable => "create_table",
329 StatementKind::CreateTableFromSource => "create_table_from_source",
330 StatementKind::CreateIndex => "create_index",
331 StatementKind::CreateType => "create_type",
332 StatementKind::CreateRole => "create_role",
333 StatementKind::CreateCluster => "create_cluster",
334 StatementKind::CreateClusterReplica => "create_cluster_replica",
335 StatementKind::CreateSecret => "create_secret",
336 StatementKind::CreateNetworkPolicy => "create_network_policy",
337 StatementKind::AlterCluster => "alter_cluster",
338 StatementKind::AlterObjectRename => "alter_object_rename",
339 StatementKind::AlterRetainHistory => "alter_retain_history",
340 StatementKind::AlterObjectSwap => "alter_object_swap",
341 StatementKind::AlterIndex => "alter_index",
342 StatementKind::AlterNetworkPolicy => "alter_network_policy",
343 StatementKind::AlterRole => "alter_role",
344 StatementKind::AlterSecret => "alter_secret",
345 StatementKind::AlterSetCluster => "alter_set_cluster",
346 StatementKind::AlterSink => "alter_sink",
347 StatementKind::AlterSource => "alter_source",
348 StatementKind::AlterSystemSet => "alter_system_set",
349 StatementKind::AlterSystemReset => "alter_system_reset",
350 StatementKind::AlterSystemResetAll => "alter_system_reset_all",
351 StatementKind::AlterOwner => "alter_owner",
352 StatementKind::AlterConnection => "alter_connection",
353 StatementKind::AlterTableAddColumn => "alter_table",
354 StatementKind::AlterMaterializedViewApplyReplacement => {
355 "alter_materialized_view_apply_replacement"
356 }
357 StatementKind::Discard => "discard",
358 StatementKind::DropObjects => "drop_objects",
359 StatementKind::DropOwned => "drop_owned",
360 StatementKind::SetVariable => "set_variable",
361 StatementKind::ResetVariable => "reset_variable",
362 StatementKind::Show => "show",
363 StatementKind::StartTransaction => "start_transaction",
364 StatementKind::SetTransaction => "set_transaction",
365 StatementKind::Commit => "commit",
366 StatementKind::Rollback => "rollback",
367 StatementKind::Subscribe => "subscribe",
368 StatementKind::ExplainPlan => "explain_plan",
369 StatementKind::ExplainPushdown => "explain_pushdown",
370 StatementKind::ExplainAnalyzeObject => "explain_analyze_object",
371 StatementKind::ExplainAnalyzeCluster => "explain_analyze_cluster",
372 StatementKind::ExplainTimestamp => "explain_timestamp",
373 StatementKind::ExplainSinkSchema => "explain_sink_schema",
374 StatementKind::Declare => "declare",
375 StatementKind::Fetch => "fetch",
376 StatementKind::Close => "close",
377 StatementKind::Prepare => "prepare",
378 StatementKind::Execute => "execute",
379 StatementKind::ExecuteUnitTest => "execute_unit_test",
380 StatementKind::Deallocate => "deallocate",
381 StatementKind::Raise => "raise",
382 StatementKind::GrantRole => "grant_role",
383 StatementKind::RevokeRole => "revoke_role",
384 StatementKind::GrantPrivileges => "grant_privileges",
385 StatementKind::RevokePrivileges => "revoke_privileges",
386 StatementKind::AlterDefaultPrivileges => "alter_default_privileges",
387 StatementKind::ReassignOwned => "reassign_owned",
388 StatementKind::ValidateConnection => "validate_connection",
389 StatementKind::Comment => "comment",
390 }
391}
392
393#[derive(Debug, Clone, PartialEq, Eq, Hash)]
395pub struct SelectStatement<T: AstInfo> {
396 pub query: Query<T>,
397 pub as_of: Option<AsOf<T>>,
398}
399
400impl<T: AstInfo> AstDisplay for SelectStatement<T> {
401 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
402 let parenthesize_show = self.query.body.starts_with_show();
409 if parenthesize_show {
410 f.write_str("(");
411 }
412 f.write_node(&self.query);
413 if parenthesize_show {
414 f.write_str(")");
415 }
416 if let Some(as_of) = &self.as_of {
417 f.write_str(" ");
418 f.write_node(as_of);
419 }
420 }
421}
422impl_display_t!(SelectStatement);
423
424#[derive(Debug, Clone, PartialEq, Eq, Hash)]
426pub struct InsertStatement<T: AstInfo> {
427 pub table_name: T::ItemName,
429 pub columns: Vec<Ident>,
431 pub source: InsertSource<T>,
433 pub returning: Vec<SelectItem<T>>,
435}
436
437impl<T: AstInfo> AstDisplay for InsertStatement<T> {
438 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
439 f.write_str("INSERT INTO ");
440 f.write_node(&self.table_name);
441 if !self.columns.is_empty() {
442 f.write_str(" (");
443 f.write_node(&display::comma_separated(&self.columns));
444 f.write_str(")");
445 }
446 f.write_str(" ");
447 f.write_node(&self.source);
448 if !self.returning.is_empty() {
449 f.write_str(" RETURNING ");
450 f.write_node(&display::comma_separated(&self.returning));
451 }
452 }
453}
454impl_display_t!(InsertStatement);
455
456#[derive(Debug, Clone, PartialEq, Eq, Hash)]
457pub enum CopyRelation<T: AstInfo> {
458 Named {
459 name: T::ItemName,
460 columns: Vec<Ident>,
461 },
462 Select(SelectStatement<T>),
463 Subscribe(SubscribeStatement<T>),
464}
465
466#[derive(Debug, Clone, PartialEq, Eq, Hash)]
467pub enum CopyDirection {
468 To,
469 From,
470}
471
472impl AstDisplay for CopyDirection {
473 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
474 f.write_str(match self {
475 CopyDirection::To => "TO",
476 CopyDirection::From => "FROM",
477 })
478 }
479}
480impl_display!(CopyDirection);
481
482#[derive(Debug, Clone, PartialEq, Eq, Hash)]
483pub enum CopyTarget<T: AstInfo> {
484 Stdin,
485 Stdout,
486 Expr(Expr<T>),
487}
488
489impl<T: AstInfo> AstDisplay for CopyTarget<T> {
490 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
491 match self {
492 CopyTarget::Stdin => f.write_str("STDIN"),
493 CopyTarget::Stdout => f.write_str("STDOUT"),
494 CopyTarget::Expr(expr) => f.write_node(expr),
495 }
496 }
497}
498impl_display_t!(CopyTarget);
499
500#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
501pub enum CopyOptionName {
502 Format,
503 Delimiter,
504 Null,
505 Escape,
506 Quote,
507 Header,
508 AwsConnection,
509 MaxFileSize,
510 Files,
511 Pattern,
512}
513
514impl AstDisplay for CopyOptionName {
515 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
516 f.write_str(match self {
517 CopyOptionName::Format => "FORMAT",
518 CopyOptionName::Delimiter => "DELIMITER",
519 CopyOptionName::Null => "NULL",
520 CopyOptionName::Escape => "ESCAPE",
521 CopyOptionName::Quote => "QUOTE",
522 CopyOptionName::Header => "HEADER",
523 CopyOptionName::AwsConnection => "AWS CONNECTION",
524 CopyOptionName::MaxFileSize => "MAX FILE SIZE",
525 CopyOptionName::Files => "FILES",
526 CopyOptionName::Pattern => "PATTERN",
527 })
528 }
529}
530
531impl WithOptionName for CopyOptionName {
532 fn redact_value(&self) -> bool {
538 match self {
539 CopyOptionName::Format
540 | CopyOptionName::Delimiter
541 | CopyOptionName::Null
542 | CopyOptionName::Escape
543 | CopyOptionName::Quote
544 | CopyOptionName::Header
545 | CopyOptionName::AwsConnection
546 | CopyOptionName::MaxFileSize => false,
547 CopyOptionName::Files | CopyOptionName::Pattern => true,
548 }
549 }
550}
551
552#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
553pub struct CopyOption<T: AstInfo> {
554 pub name: CopyOptionName,
555 pub value: Option<WithOptionValue<T>>,
556}
557impl_display_for_with_option!(CopyOption);
558
559#[derive(Debug, Clone, PartialEq, Eq, Hash)]
561pub struct CopyStatement<T: AstInfo> {
562 pub relation: CopyRelation<T>,
564 pub direction: CopyDirection,
566 pub target: CopyTarget<T>,
568 pub options: Vec<CopyOption<T>>,
570}
571
572impl<T: AstInfo> AstDisplay for CopyStatement<T> {
573 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
574 f.write_str("COPY ");
575 match &self.relation {
576 CopyRelation::Named { name, columns } => {
577 f.write_node(name);
578 if !columns.is_empty() {
579 f.write_str("(");
580 f.write_node(&display::comma_separated(columns));
581 f.write_str(")");
582 }
583 }
584 CopyRelation::Select(query) => {
585 f.write_str("(");
586 f.write_node(query);
587 f.write_str(")");
588 }
589 CopyRelation::Subscribe(query) => {
590 f.write_str("(");
591 f.write_node(query);
592 f.write_str(")");
593 }
594 };
595 f.write_str(" ");
596 f.write_node(&self.direction);
597 f.write_str(" ");
598 f.write_node(&self.target);
599 if !self.options.is_empty() {
600 f.write_str(" WITH (");
601 f.write_node(&display::comma_separated(&self.options));
602 f.write_str(")");
603 }
604 }
605}
606impl_display_t!(CopyStatement);
607
608#[derive(Debug, Clone, PartialEq, Eq, Hash)]
610pub struct UpdateStatement<T: AstInfo> {
611 pub table_name: T::ItemName,
613 pub alias: Option<TableAlias>,
614 pub assignments: Vec<Assignment<T>>,
616 pub selection: Option<Expr<T>>,
618}
619
620impl<T: AstInfo> AstDisplay for UpdateStatement<T> {
621 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
622 f.write_str("UPDATE ");
623 f.write_node(&self.table_name);
624 if let Some(alias) = &self.alias {
625 f.write_str(" AS ");
626 f.write_node(alias);
627 }
628 if !self.assignments.is_empty() {
629 f.write_str(" SET ");
630 f.write_node(&display::comma_separated(&self.assignments));
631 }
632 if let Some(selection) = &self.selection {
633 f.write_str(" WHERE ");
634 f.write_node(selection);
635 }
636 }
637}
638impl_display_t!(UpdateStatement);
639
640#[derive(Debug, Clone, PartialEq, Eq, Hash)]
642pub struct DeleteStatement<T: AstInfo> {
643 pub table_name: T::ItemName,
645 pub alias: Option<TableAlias>,
647 pub using: Vec<TableWithJoins<T>>,
649 pub selection: Option<Expr<T>>,
651}
652
653impl<T: AstInfo> AstDisplay for DeleteStatement<T> {
654 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
655 f.write_str("DELETE FROM ");
656 f.write_node(&self.table_name);
657 if let Some(alias) = &self.alias {
658 f.write_str(" AS ");
659 f.write_node(alias);
660 }
661 if !self.using.is_empty() {
662 f.write_str(" USING ");
663 f.write_node(&display::comma_separated(&self.using));
664 }
665 if let Some(selection) = &self.selection {
666 f.write_str(" WHERE ");
667 f.write_node(selection);
668 }
669 }
670}
671impl_display_t!(DeleteStatement);
672
673#[derive(Debug, Clone, PartialEq, Eq, Hash)]
675pub struct CreateDatabaseStatement {
676 pub name: UnresolvedDatabaseName,
677 pub if_not_exists: bool,
678}
679
680impl AstDisplay for CreateDatabaseStatement {
681 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
682 f.write_str("CREATE DATABASE ");
683 if self.if_not_exists {
684 f.write_str("IF NOT EXISTS ");
685 }
686 f.write_node(&self.name);
687 }
688}
689impl_display!(CreateDatabaseStatement);
690
691#[derive(Debug, Clone, PartialEq, Eq, Hash)]
693pub struct CreateSchemaStatement {
694 pub name: UnresolvedSchemaName,
695 pub if_not_exists: bool,
696}
697
698impl AstDisplay for CreateSchemaStatement {
699 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
700 f.write_str("CREATE SCHEMA ");
701 if self.if_not_exists {
702 f.write_str("IF NOT EXISTS ");
703 }
704 f.write_node(&self.name);
705 }
706}
707impl_display!(CreateSchemaStatement);
708
709#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
710pub struct ConnectionDefaultAwsPrivatelink<T: AstInfo> {
711 pub connection: T::ItemName,
712 pub port: Option<u16>,
714}
715
716impl<T: AstInfo> AstDisplay for ConnectionDefaultAwsPrivatelink<T> {
717 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
718 f.write_node(&self.connection);
719 if let Some(port) = self.port {
720 f.write_str(" (PORT ");
721 f.write_node(&display::escape_single_quote_string(&port.to_string()));
722 f.write_str(")");
723 }
724 }
725}
726impl_display_t!(ConnectionDefaultAwsPrivatelink);
727
728#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
729pub struct KafkaMatchingBrokerRule<T: AstInfo> {
732 pub pattern: ConnectionRulePattern,
734 pub tunnel: KafkaBrokerAwsPrivatelink<T>,
736}
737
738#[derive(
739 Debug,
740 Clone,
741 PartialEq,
742 Eq,
743 Hash,
744 PartialOrd,
745 Ord,
746 Serialize,
747 Deserialize
748)]
749pub struct ConnectionRulePattern {
751 pub prefix_wildcard: bool,
753 pub literal_match: String,
755 pub suffix_wildcard: bool,
757}
758
759impl<T: AstInfo> AstDisplay for KafkaMatchingBrokerRule<T> {
760 fn fmt<W>(&self, f: &mut AstFormatter<W>)
761 where
762 W: fmt::Write,
763 {
764 f.write_str("MATCHING ");
765 f.write_node(&self.pattern);
766 f.write_str(" ");
767 f.write_node(&self.tunnel);
768 }
769}
770impl_display_t!(KafkaMatchingBrokerRule);
771
772impl AstDisplay for ConnectionRulePattern {
773 fn fmt<W>(&self, f: &mut AstFormatter<W>)
774 where
775 W: fmt::Write,
776 {
777 f.write_str("'");
778 if self.prefix_wildcard {
779 f.write_str("*");
780 }
781 f.write_node(&display::escape_single_quote_string(&self.literal_match));
782 if self.suffix_wildcard {
783 f.write_str("*");
784 }
785 f.write_str("'");
786 }
787}
788impl_display!(ConnectionRulePattern);
789
790#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
791pub struct KafkaBroker<T: AstInfo> {
792 pub address: String,
793 pub tunnel: KafkaBrokerTunnel<T>,
794}
795
796impl<T: AstInfo> AstDisplay for KafkaBroker<T> {
797 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
798 f.write_str("'");
799 f.write_node(&display::escape_single_quote_string(&self.address));
800 f.write_str("'");
801 f.write_node(&self.tunnel);
802 }
803}
804
805impl_display_t!(KafkaBroker);
806
807#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
808pub enum KafkaBrokerTunnel<T: AstInfo> {
809 Direct,
810 AwsPrivatelink(KafkaBrokerAwsPrivatelink<T>),
811 SshTunnel(T::ItemName),
812}
813
814impl<T: AstInfo> AstDisplay for KafkaBrokerTunnel<T> {
815 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
816 use KafkaBrokerTunnel::*;
817 match self {
818 Direct => {}
819 AwsPrivatelink(aws) => {
820 f.write_str(" ");
821 f.write_node(aws);
822 }
823 Self::SshTunnel(connection) => {
824 f.write_str("USING SSH TUNNEL ");
825 f.write_node(connection);
826 }
827 }
828 }
829}
830
831impl_display_t!(KafkaBrokerTunnel);
832
833#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
834pub enum KafkaBrokerAwsPrivatelinkOptionName {
835 AvailabilityZone,
836 Port,
837}
838
839impl AstDisplay for KafkaBrokerAwsPrivatelinkOptionName {
840 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
841 match self {
842 Self::AvailabilityZone => f.write_str("AVAILABILITY ZONE"),
843 Self::Port => f.write_str("PORT"),
844 }
845 }
846}
847impl_display!(KafkaBrokerAwsPrivatelinkOptionName);
848
849impl WithOptionName for KafkaBrokerAwsPrivatelinkOptionName {
850 fn redact_value(&self) -> bool {
856 match self {
857 Self::AvailabilityZone | Self::Port => false,
858 }
859 }
860}
861
862#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
863pub struct KafkaBrokerAwsPrivatelinkOption<T: AstInfo> {
864 pub name: KafkaBrokerAwsPrivatelinkOptionName,
865 pub value: Option<WithOptionValue<T>>,
866}
867impl_display_for_with_option!(KafkaBrokerAwsPrivatelinkOption);
868impl_display_t!(KafkaBrokerAwsPrivatelinkOption);
869
870#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
871pub struct KafkaBrokerAwsPrivatelink<T: AstInfo> {
872 pub connection: T::ItemName,
873 pub options: Vec<KafkaBrokerAwsPrivatelinkOption<T>>,
874}
875
876impl<T: AstInfo> AstDisplay for KafkaBrokerAwsPrivatelink<T> {
877 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
878 f.write_str("USING AWS PRIVATELINK ");
879 f.write_node(&self.connection);
880 if !self.options.is_empty() {
881 f.write_str(" (");
882 f.write_node(&display::comma_separated(&self.options));
883 f.write_str(")");
884 }
885 }
886}
887impl_display_t!(KafkaBrokerAwsPrivatelink);
888
889#[derive(Debug, Clone, PartialEq, Eq, Hash)]
891pub struct CreateConnectionStatement<T: AstInfo> {
892 pub name: UnresolvedItemName,
893 pub connection_type: CreateConnectionType,
894 pub if_not_exists: bool,
895 pub values: Vec<ConnectionOption<T>>,
896 pub with_options: Vec<CreateConnectionOption<T>>,
897}
898
899impl<T: AstInfo> AstDisplay for CreateConnectionStatement<T> {
900 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
901 f.write_str("CREATE CONNECTION ");
902 if self.if_not_exists {
903 f.write_str("IF NOT EXISTS ");
904 }
905 f.write_node(&self.name);
906 f.write_str(" TO ");
907 self.connection_type.fmt(f);
908 f.write_str(" (");
909 f.write_node(&display::comma_separated(&self.values));
910 f.write_str(")");
911
912 if !self.with_options.is_empty() {
913 f.write_str(" WITH (");
914 f.write_node(&display::comma_separated(&self.with_options));
915 f.write_str(")");
916 }
917 }
918}
919impl_display_t!(CreateConnectionStatement);
920
921#[derive(Debug, Clone, PartialEq, Eq, Hash)]
923pub struct ValidateConnectionStatement<T: AstInfo> {
924 pub name: T::ItemName,
926}
927
928impl<T: AstInfo> AstDisplay for ValidateConnectionStatement<T> {
929 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
930 f.write_str("VALIDATE CONNECTION ");
931 f.write_node(&self.name);
932 }
933}
934impl_display_t!(ValidateConnectionStatement);
935
936#[derive(Debug, Clone, PartialEq, Eq, Hash)]
938pub struct CreateWebhookSourceStatement<T: AstInfo> {
939 pub name: UnresolvedItemName,
940 pub is_table: bool,
941 pub if_not_exists: bool,
942 pub body_format: Format<T>,
943 pub include_headers: CreateWebhookSourceIncludeHeaders,
944 pub validate_using: Option<CreateWebhookSourceCheck<T>>,
945 pub in_cluster: Option<T::ClusterName>,
946}
947
948impl<T: AstInfo> AstDisplay for CreateWebhookSourceStatement<T> {
949 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
950 f.write_str("CREATE ");
951
952 if self.is_table {
953 f.write_str("TABLE ");
954 } else {
955 f.write_str("SOURCE ");
956 }
957
958 if self.if_not_exists {
959 f.write_str("IF NOT EXISTS ");
960 }
961 f.write_node(&self.name);
962
963 if !self.is_table {
965 if let Some(cluster_name) = &self.in_cluster {
966 f.write_str(" IN CLUSTER ");
967 f.write_node(cluster_name);
968 }
969 }
970
971 f.write_str(" FROM WEBHOOK ");
972
973 f.write_str("BODY FORMAT ");
974 f.write_node(&self.body_format);
975
976 f.write_node(&self.include_headers);
977
978 if let Some(validate) = &self.validate_using {
979 f.write_str(" ");
980 f.write_node(validate);
981 }
982 }
983}
984
985impl_display_t!(CreateWebhookSourceStatement);
986
987#[derive(Debug, Clone, PartialEq, Eq, Hash)]
989pub struct CreateWebhookSourceCheck<T: AstInfo> {
990 pub options: Option<CreateWebhookSourceCheckOptions<T>>,
991 pub using: Expr<T>,
992}
993
994impl<T: AstInfo> AstDisplay for CreateWebhookSourceCheck<T> {
995 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
996 f.write_str("CHECK (");
997
998 if let Some(options) = &self.options {
999 f.write_node(options);
1000 f.write_str(" ");
1001 }
1002
1003 f.write_node(&self.using);
1004 f.write_str(")");
1005 }
1006}
1007
1008impl_display_t!(CreateWebhookSourceCheck);
1009
1010#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1012pub struct CreateWebhookSourceCheckOptions<T: AstInfo> {
1013 pub secrets: Vec<CreateWebhookSourceSecret<T>>,
1014 pub headers: Vec<CreateWebhookSourceHeader>,
1015 pub bodies: Vec<CreateWebhookSourceBody>,
1016}
1017
1018impl<T: AstInfo> AstDisplay for CreateWebhookSourceCheckOptions<T> {
1019 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1020 f.write_str("WITH (");
1021
1022 let mut delim = "";
1023 if !self.headers.is_empty() {
1024 f.write_node(&display::comma_separated(&self.headers[..]));
1025 delim = ", ";
1026 }
1027 if !self.bodies.is_empty() {
1028 f.write_str(delim);
1029 f.write_node(&display::comma_separated(&self.bodies[..]));
1030 delim = ", ";
1031 }
1032 if !self.secrets.is_empty() {
1033 f.write_str(delim);
1034 f.write_node(&display::comma_separated(&self.secrets[..]));
1035 }
1036
1037 f.write_str(")");
1038 }
1039}
1040
1041impl_display_t!(CreateWebhookSourceCheckOptions);
1042
1043#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1045pub struct CreateWebhookSourceSecret<T: AstInfo> {
1046 pub secret: T::ItemName,
1047 pub alias: Option<Ident>,
1048 pub use_bytes: bool,
1049}
1050
1051impl<T: AstInfo> AstDisplay for CreateWebhookSourceSecret<T> {
1052 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1053 f.write_str("SECRET ");
1054 f.write_node(&self.secret);
1055
1056 if let Some(alias) = &self.alias {
1057 f.write_str(" AS ");
1058 f.write_node(alias);
1059 }
1060
1061 if self.use_bytes {
1062 f.write_str(" BYTES");
1063 }
1064 }
1065}
1066
1067impl_display_t!(CreateWebhookSourceSecret);
1068
1069#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1071pub struct CreateWebhookSourceHeader {
1072 pub alias: Option<Ident>,
1073 pub use_bytes: bool,
1074}
1075
1076impl AstDisplay for CreateWebhookSourceHeader {
1077 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1078 f.write_str("HEADERS");
1079
1080 if let Some(alias) = &self.alias {
1081 f.write_str(" AS ");
1082 f.write_node(alias);
1083 }
1084
1085 if self.use_bytes {
1086 f.write_str(" BYTES");
1087 }
1088 }
1089}
1090
1091impl_display!(CreateWebhookSourceHeader);
1092
1093#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1095pub struct CreateWebhookSourceBody {
1096 pub alias: Option<Ident>,
1097 pub use_bytes: bool,
1098}
1099
1100impl AstDisplay for CreateWebhookSourceBody {
1101 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1102 f.write_str("BODY");
1103
1104 if let Some(alias) = &self.alias {
1105 f.write_str(" AS ");
1106 f.write_node(alias);
1107 }
1108
1109 if self.use_bytes {
1110 f.write_str(" BYTES");
1111 }
1112 }
1113}
1114
1115impl_display!(CreateWebhookSourceBody);
1116
1117#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)]
1119pub struct CreateWebhookSourceIncludeHeaders {
1120 pub mappings: Vec<CreateWebhookSourceMapHeader>,
1122 pub column: Option<Vec<CreateWebhookSourceFilterHeader>>,
1124}
1125
1126impl AstDisplay for CreateWebhookSourceIncludeHeaders {
1127 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1128 if !self.mappings.is_empty() {
1129 f.write_str(" ");
1130 }
1131 f.write_node(&display::separated(&self.mappings[..], " "));
1132
1133 if let Some(column) = &self.column {
1134 f.write_str(" INCLUDE HEADERS");
1135
1136 if !column.is_empty() {
1137 f.write_str(" ");
1138 f.write_str("(");
1139 f.write_node(&display::comma_separated(&column[..]));
1140 f.write_str(")");
1141 }
1142 }
1143 }
1144}
1145
1146impl_display!(CreateWebhookSourceIncludeHeaders);
1147
1148#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1149pub struct CreateWebhookSourceFilterHeader {
1150 pub block: bool,
1151 pub header_name: String,
1152}
1153
1154impl AstDisplay for CreateWebhookSourceFilterHeader {
1155 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1156 if self.block {
1157 f.write_str("NOT ");
1158 }
1159 f.write_node(&display::escaped_string_literal(&self.header_name));
1160 }
1161}
1162
1163impl_display!(CreateWebhookSourceFilterHeader);
1164
1165#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1167pub struct CreateWebhookSourceMapHeader {
1168 pub header_name: String,
1169 pub column_name: Ident,
1170 pub use_bytes: bool,
1171}
1172
1173impl AstDisplay for CreateWebhookSourceMapHeader {
1174 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1175 f.write_str("INCLUDE HEADER ");
1176
1177 f.write_node(&display::escaped_string_literal(&self.header_name));
1178
1179 f.write_str(" AS ");
1180 f.write_node(&self.column_name);
1181
1182 if self.use_bytes {
1183 f.write_str(" BYTES");
1184 }
1185 }
1186}
1187
1188impl_display!(CreateWebhookSourceMapHeader);
1189
1190#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1192pub struct CreateSourceStatement<T: AstInfo> {
1193 pub name: UnresolvedItemName,
1194 pub in_cluster: Option<T::ClusterName>,
1195 pub col_names: Vec<Ident>,
1196 pub connection: CreateSourceConnection<T>,
1197 pub include_metadata: Vec<SourceIncludeMetadata>,
1198 pub format: Option<FormatSpecifier<T>>,
1199 pub envelope: Option<SourceEnvelope>,
1200 pub if_not_exists: bool,
1201 pub key_constraint: Option<KeyConstraint>,
1202 pub with_options: Vec<CreateSourceOption<T>>,
1203 pub external_references: Option<ExternalReferences>,
1204 pub progress_subsource: Option<DeferredItemName<T>>,
1205}
1206
1207impl<T: AstInfo> AstDisplay for CreateSourceStatement<T> {
1208 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1209 f.write_str("CREATE SOURCE ");
1210 if self.if_not_exists {
1211 f.write_str("IF NOT EXISTS ");
1212 }
1213 f.write_node(&self.name);
1214 if !self.col_names.is_empty() {
1215 f.write_str(" (");
1216 f.write_node(&display::comma_separated(&self.col_names));
1217 if let Some(key_constraint) = &self.key_constraint {
1218 f.write_str(", ");
1219 f.write_node(key_constraint);
1220 }
1221 f.write_str(")");
1222 } else if let Some(key_constraint) = &self.key_constraint {
1223 f.write_str(" (");
1224 f.write_node(key_constraint);
1225 f.write_str(")")
1226 }
1227 if let Some(cluster) = &self.in_cluster {
1228 f.write_str(" IN CLUSTER ");
1229 f.write_node(cluster);
1230 }
1231 f.write_str(" FROM ");
1232 f.write_node(&self.connection);
1233 if let Some(format) = &self.format {
1234 f.write_str(" ");
1235 f.write_node(format);
1236 }
1237 if !self.include_metadata.is_empty() {
1238 f.write_str(" INCLUDE ");
1239 f.write_node(&display::comma_separated(&self.include_metadata));
1240 }
1241
1242 if let Some(envelope) = &self.envelope {
1243 f.write_str(" ENVELOPE ");
1244 f.write_node(envelope);
1245 }
1246
1247 if let Some(subsources) = &self.external_references {
1248 f.write_str(" ");
1249 f.write_node(subsources);
1250 }
1251
1252 if let Some(progress) = &self.progress_subsource {
1253 f.write_str(" EXPOSE PROGRESS AS ");
1254 f.write_node(progress);
1255 }
1256
1257 if !self.with_options.is_empty() {
1258 f.write_str(" WITH (");
1259 f.write_node(&display::comma_separated(&self.with_options));
1260 f.write_str(")");
1261 }
1262 }
1263}
1264impl_display_t!(CreateSourceStatement);
1265
1266#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1268pub struct ExternalReferenceExport {
1269 pub reference: UnresolvedItemName,
1270 pub alias: Option<UnresolvedItemName>,
1271}
1272
1273impl AstDisplay for ExternalReferenceExport {
1274 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1275 f.write_node(&self.reference);
1276 if let Some(alias) = &self.alias {
1277 f.write_str(" AS ");
1278 f.write_node(alias);
1279 }
1280 }
1281}
1282impl_display!(ExternalReferenceExport);
1283
1284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1287pub enum ExternalReferences {
1288 SubsetTables(Vec<ExternalReferenceExport>),
1290 SubsetSchemas(Vec<Ident>),
1292 All,
1294}
1295
1296impl AstDisplay for ExternalReferences {
1297 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1298 match self {
1299 Self::SubsetTables(tables) => {
1300 f.write_str("FOR TABLES (");
1301 f.write_node(&display::comma_separated(tables));
1302 f.write_str(")");
1303 }
1304 Self::SubsetSchemas(schemas) => {
1305 f.write_str("FOR SCHEMAS (");
1306 f.write_node(&display::comma_separated(schemas));
1307 f.write_str(")");
1308 }
1309 Self::All => f.write_str("FOR ALL TABLES"),
1310 }
1311 }
1312}
1313impl_display!(ExternalReferences);
1314
1315#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1317pub enum CreateSubsourceOptionName {
1318 Progress,
1319 ExternalReference,
1321 RetainHistory,
1323 TextColumns,
1325 ExcludeColumns,
1327 Details,
1330}
1331
1332impl AstDisplay for CreateSubsourceOptionName {
1333 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1334 f.write_str(match self {
1335 CreateSubsourceOptionName::Progress => "PROGRESS",
1336 CreateSubsourceOptionName::ExternalReference => "EXTERNAL REFERENCE",
1337 CreateSubsourceOptionName::RetainHistory => "RETAIN HISTORY",
1338 CreateSubsourceOptionName::TextColumns => "TEXT COLUMNS",
1339 CreateSubsourceOptionName::ExcludeColumns => "EXCLUDE COLUMNS",
1340 CreateSubsourceOptionName::Details => "DETAILS",
1341 })
1342 }
1343}
1344
1345impl WithOptionName for CreateSubsourceOptionName {
1346 fn redact_value(&self) -> bool {
1352 match self {
1353 CreateSubsourceOptionName::Progress
1354 | CreateSubsourceOptionName::ExternalReference
1355 | CreateSubsourceOptionName::RetainHistory
1356 | CreateSubsourceOptionName::Details
1357 | CreateSubsourceOptionName::TextColumns
1358 | CreateSubsourceOptionName::ExcludeColumns => false,
1359 }
1360 }
1361}
1362
1363#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1364pub struct CreateSubsourceOption<T: AstInfo> {
1365 pub name: CreateSubsourceOptionName,
1366 pub value: Option<WithOptionValue<T>>,
1367}
1368impl_display_for_with_option!(CreateSubsourceOption);
1369
1370#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1372pub struct CreateSubsourceStatement<T: AstInfo> {
1373 pub name: UnresolvedItemName,
1374 pub columns: Vec<ColumnDef<T>>,
1375 pub of_source: Option<T::ItemName>,
1378 pub constraints: Vec<TableConstraint<T>>,
1379 pub if_not_exists: bool,
1380 pub with_options: Vec<CreateSubsourceOption<T>>,
1381}
1382
1383impl<T: AstInfo> AstDisplay for CreateSubsourceStatement<T> {
1384 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1385 f.write_str("CREATE SUBSOURCE ");
1386 if self.if_not_exists {
1387 f.write_str("IF NOT EXISTS ");
1388 }
1389
1390 f.write_node(&self.name);
1391 f.write_str(" (");
1392 f.write_node(&display::comma_separated(&self.columns));
1393 if !self.constraints.is_empty() {
1394 f.write_str(", ");
1395 f.write_node(&display::comma_separated(&self.constraints));
1396 }
1397 f.write_str(")");
1398
1399 if let Some(of_source) = &self.of_source {
1400 f.write_str(" OF SOURCE ");
1401 f.write_node(of_source);
1402 }
1403
1404 if !self.with_options.is_empty() {
1405 f.write_str(" WITH (");
1406 f.write_node(&display::comma_separated(&self.with_options));
1407 f.write_str(")");
1408 }
1409 }
1410}
1411impl_display_t!(CreateSubsourceStatement);
1412
1413#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1415pub enum CreateSinkOptionName {
1416 Snapshot,
1417 Version,
1418 PartitionStrategy,
1419 CommitInterval,
1420}
1421
1422impl AstDisplay for CreateSinkOptionName {
1423 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1424 match self {
1425 CreateSinkOptionName::Snapshot => {
1426 f.write_str("SNAPSHOT");
1427 }
1428 CreateSinkOptionName::Version => {
1429 f.write_str("VERSION");
1430 }
1431 CreateSinkOptionName::PartitionStrategy => {
1432 f.write_str("PARTITION STRATEGY");
1433 }
1434 CreateSinkOptionName::CommitInterval => {
1435 f.write_str("COMMIT INTERVAL");
1436 }
1437 }
1438 }
1439}
1440
1441impl WithOptionName for CreateSinkOptionName {
1442 fn redact_value(&self) -> bool {
1448 match self {
1449 CreateSinkOptionName::Snapshot => false,
1450 CreateSinkOptionName::Version => false,
1451 CreateSinkOptionName::PartitionStrategy => false,
1452 CreateSinkOptionName::CommitInterval => false,
1453 }
1454 }
1455}
1456
1457#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1458pub struct CreateSinkOption<T: AstInfo> {
1459 pub name: CreateSinkOptionName,
1460 pub value: Option<WithOptionValue<T>>,
1461}
1462impl_display_for_with_option!(CreateSinkOption);
1463
1464#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1466pub struct CreateSinkStatement<T: AstInfo> {
1467 pub name: Option<UnresolvedItemName>,
1468 pub in_cluster: Option<T::ClusterName>,
1469 pub if_not_exists: bool,
1470 pub from: T::ItemName,
1471 pub connection: CreateSinkConnection<T>,
1472 pub format: Option<FormatSpecifier<T>>,
1473 pub envelope: Option<SinkEnvelope>,
1474 pub mode: Option<IcebergSinkMode>,
1475 pub with_options: Vec<CreateSinkOption<T>>,
1476}
1477
1478impl<T: AstInfo> AstDisplay for CreateSinkStatement<T> {
1479 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1480 f.write_str("CREATE SINK ");
1481 if self.if_not_exists {
1482 f.write_str("IF NOT EXISTS ");
1483 }
1484 if let Some(name) = &self.name {
1485 f.write_node(&name);
1486 f.write_str(" ");
1487 }
1488 if let Some(cluster) = &self.in_cluster {
1489 f.write_str("IN CLUSTER ");
1490 f.write_node(cluster);
1491 f.write_str(" ");
1492 }
1493 f.write_str("FROM ");
1494 f.write_node(&self.from);
1495 f.write_str(" INTO ");
1496 f.write_node(&self.connection);
1497 if let Some(format) = &self.format {
1498 f.write_str(" ");
1499 f.write_node(format);
1500 }
1501 if let Some(envelope) = &self.envelope {
1502 f.write_str(" ENVELOPE ");
1503 f.write_node(envelope);
1504 }
1505 if let Some(mode) = &self.mode {
1506 f.write_str(" MODE ");
1507 f.write_node(mode);
1508 }
1509
1510 if !self.with_options.is_empty() {
1511 f.write_str(" WITH (");
1512 f.write_node(&display::comma_separated(&self.with_options));
1513 f.write_str(")");
1514 }
1515 }
1516}
1517impl_display_t!(CreateSinkStatement);
1518
1519#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1521pub enum CreateMetricSinkOptionName {
1522 Prefix,
1523}
1524
1525impl AstDisplay for CreateMetricSinkOptionName {
1526 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1527 match self {
1528 CreateMetricSinkOptionName::Prefix => {
1529 f.write_str("PREFIX");
1530 }
1531 }
1532 }
1533}
1534
1535impl WithOptionName for CreateMetricSinkOptionName {
1536 fn redact_value(&self) -> bool {
1542 match self {
1543 CreateMetricSinkOptionName::Prefix => false,
1544 }
1545 }
1546}
1547
1548#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1549pub struct CreateMetricSinkOption<T: AstInfo> {
1550 pub name: CreateMetricSinkOptionName,
1551 pub value: Option<WithOptionValue<T>>,
1552}
1553impl_display_for_with_option!(CreateMetricSinkOption);
1554
1555#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1557pub struct CreateMetricSinkStatement<T: AstInfo> {
1558 pub name: UnresolvedItemName,
1559 pub in_cluster: Option<T::ClusterName>,
1560 pub if_not_exists: bool,
1561 pub from: T::ItemName,
1562 pub with_options: Vec<CreateMetricSinkOption<T>>,
1563}
1564
1565impl<T: AstInfo> AstDisplay for CreateMetricSinkStatement<T> {
1566 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1567 f.write_str("CREATE METRIC SINK ");
1568 if self.if_not_exists {
1569 f.write_str("IF NOT EXISTS ");
1570 }
1571 f.write_node(&self.name);
1572 f.write_str(" ");
1573 if let Some(cluster) = &self.in_cluster {
1574 f.write_str("IN CLUSTER ");
1575 f.write_node(cluster);
1576 f.write_str(" ");
1577 }
1578 f.write_str("FROM ");
1579 f.write_node(&self.from);
1580
1581 if !self.with_options.is_empty() {
1584 f.write_str(" WITH (");
1585 f.write_node(&display::comma_separated(&self.with_options));
1586 f.write_str(")");
1587 }
1588 }
1589}
1590impl_display_t!(CreateMetricSinkStatement);
1591
1592#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1593pub struct ViewDefinition<T: AstInfo> {
1594 pub name: UnresolvedItemName,
1596 pub columns: Vec<Ident>,
1597 pub query: Query<T>,
1598}
1599
1600impl<T: AstInfo> AstDisplay for ViewDefinition<T> {
1601 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1602 f.write_node(&self.name);
1603
1604 if !self.columns.is_empty() {
1605 f.write_str(" (");
1606 f.write_node(&display::comma_separated(&self.columns));
1607 f.write_str(")");
1608 }
1609
1610 f.write_str(" AS ");
1611 f.write_node(&self.query);
1612 }
1613}
1614impl_display_t!(ViewDefinition);
1615
1616#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1618pub struct CreateViewStatement<T: AstInfo> {
1619 pub if_exists: IfExistsBehavior,
1620 pub temporary: bool,
1621 pub definition: ViewDefinition<T>,
1622}
1623
1624impl<T: AstInfo> AstDisplay for CreateViewStatement<T> {
1625 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1626 f.write_str("CREATE");
1627 if self.if_exists == IfExistsBehavior::Replace {
1628 f.write_str(" OR REPLACE");
1629 }
1630 if self.temporary {
1631 f.write_str(" TEMPORARY");
1632 }
1633
1634 f.write_str(" VIEW");
1635
1636 if self.if_exists == IfExistsBehavior::Skip {
1637 f.write_str(" IF NOT EXISTS");
1638 }
1639
1640 f.write_str(" ");
1641 f.write_node(&self.definition);
1642 }
1643}
1644impl_display_t!(CreateViewStatement);
1645
1646#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1648pub struct CreateMaterializedViewStatement<T: AstInfo> {
1649 pub if_exists: IfExistsBehavior,
1650 pub name: UnresolvedItemName,
1651 pub columns: Vec<Ident>,
1652 pub replacement_for: Option<T::ItemName>,
1653 pub in_cluster: Option<T::ClusterName>,
1654 pub in_cluster_replica: Option<Ident>,
1655 pub query: Query<T>,
1656 pub as_of: Option<u64>,
1657 pub with_options: Vec<MaterializedViewOption<T>>,
1658}
1659
1660impl<T: AstInfo> AstDisplay for CreateMaterializedViewStatement<T> {
1661 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1662 f.write_str("CREATE");
1663 if self.if_exists == IfExistsBehavior::Replace {
1664 f.write_str(" OR REPLACE");
1665 }
1666 if self.replacement_for.is_some() {
1667 f.write_str(" REPLACEMENT");
1668 }
1669
1670 f.write_str(" MATERIALIZED VIEW");
1671
1672 if self.if_exists == IfExistsBehavior::Skip {
1673 f.write_str(" IF NOT EXISTS");
1674 }
1675
1676 f.write_str(" ");
1677 f.write_node(&self.name);
1678
1679 if !self.columns.is_empty() {
1680 f.write_str(" (");
1681 f.write_node(&display::comma_separated(&self.columns));
1682 f.write_str(")");
1683 }
1684
1685 if let Some(target) = &self.replacement_for {
1686 f.write_str(" FOR ");
1687 f.write_node(target);
1688 }
1689
1690 match (&self.in_cluster, &self.in_cluster_replica) {
1691 (Some(cluster), Some(replica)) => {
1692 f.write_str(" IN CLUSTER ");
1693 f.write_node(cluster);
1694 f.write_str(" REPLICA ");
1695 f.write_node(replica);
1696 }
1697 (Some(cluster), None) => {
1698 f.write_str(" IN CLUSTER ");
1699 f.write_node(cluster);
1700 }
1701 (None, Some(replica)) => {
1702 f.write_str(" IN REPLICA ");
1703 f.write_node(replica);
1704 }
1705 (None, None) => {}
1706 }
1707
1708 if !self.with_options.is_empty() {
1709 f.write_str(" WITH (");
1710 f.write_node(&display::comma_separated(&self.with_options));
1711 f.write_str(")");
1712 }
1713
1714 f.write_str(" AS ");
1715 f.write_node(&self.query);
1716
1717 if let Some(time) = &self.as_of {
1718 f.write_str(" AS OF ");
1719 f.write_str(time);
1720 }
1721 }
1722}
1723impl_display_t!(CreateMaterializedViewStatement);
1724
1725#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1727pub struct AlterSetClusterStatement<T: AstInfo> {
1728 pub if_exists: bool,
1729 pub name: UnresolvedItemName,
1730 pub object_type: ObjectType,
1731 pub set_cluster: T::ClusterName,
1732}
1733
1734impl<T: AstInfo> AstDisplay for AlterSetClusterStatement<T> {
1735 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1736 f.write_str("ALTER ");
1737 f.write_node(&self.object_type);
1738
1739 if self.if_exists {
1740 f.write_str(" IF EXISTS");
1741 }
1742
1743 f.write_str(" ");
1744 f.write_node(&self.name);
1745
1746 f.write_str(" SET CLUSTER ");
1747 f.write_node(&self.set_cluster);
1748 }
1749}
1750impl_display_t!(AlterSetClusterStatement);
1751
1752#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1754pub struct CreateTableStatement<T: AstInfo> {
1755 pub name: UnresolvedItemName,
1757 pub columns: Vec<ColumnDef<T>>,
1759 pub constraints: Vec<TableConstraint<T>>,
1760 pub if_not_exists: bool,
1761 pub temporary: bool,
1762 pub with_options: Vec<TableOption<T>>,
1763}
1764
1765impl<T: AstInfo> AstDisplay for CreateTableStatement<T> {
1766 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1767 let Self {
1768 name,
1769 columns,
1770 constraints,
1771 if_not_exists,
1772 temporary,
1773 with_options,
1774 } = self;
1775 f.write_str("CREATE ");
1776 if *temporary {
1777 f.write_str("TEMPORARY ");
1778 }
1779 f.write_str("TABLE ");
1780 if *if_not_exists {
1781 f.write_str("IF NOT EXISTS ");
1782 }
1783 f.write_node(name);
1784 f.write_str(" (");
1785 f.write_node(&display::comma_separated(columns));
1786 if !self.constraints.is_empty() {
1787 if !columns.is_empty() {
1788 f.write_str(", ");
1789 }
1790 f.write_node(&display::comma_separated(constraints));
1791 }
1792 f.write_str(")");
1793 if !with_options.is_empty() {
1794 f.write_str(" WITH (");
1795 f.write_node(&display::comma_separated(&self.with_options));
1796 f.write_str(")");
1797 }
1798 }
1799}
1800impl_display_t!(CreateTableStatement);
1801
1802#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1803pub enum TableOptionName {
1804 PartitionBy,
1806 RetainHistory,
1808 RedactedTest,
1810}
1811
1812impl AstDisplay for TableOptionName {
1813 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1814 match self {
1815 TableOptionName::PartitionBy => {
1816 f.write_str("PARTITION BY");
1817 }
1818 TableOptionName::RetainHistory => {
1819 f.write_str("RETAIN HISTORY");
1820 }
1821 TableOptionName::RedactedTest => {
1822 f.write_str("REDACTED");
1823 }
1824 }
1825 }
1826}
1827
1828impl WithOptionName for TableOptionName {
1829 fn redact_value(&self) -> bool {
1835 match self {
1836 TableOptionName::PartitionBy => true,
1839 TableOptionName::RetainHistory => false,
1840 TableOptionName::RedactedTest => true,
1841 }
1842 }
1843}
1844
1845#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1846pub struct TableOption<T: AstInfo> {
1847 pub name: TableOptionName,
1848 pub value: Option<WithOptionValue<T>>,
1849}
1850impl_display_for_with_option!(TableOption);
1851
1852#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1853pub enum TableFromSourceOptionName {
1854 TextColumns,
1856 ExcludeColumns,
1858 ExcludeConstraints,
1862 ExcludeAllConstraints,
1865 ExcludeAllNotNullConstraints,
1867 Details,
1871 PartitionBy,
1873 RetainHistory,
1875}
1876
1877impl AstDisplay for TableFromSourceOptionName {
1878 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1879 f.write_str(match self {
1880 TableFromSourceOptionName::TextColumns => "TEXT COLUMNS",
1881 TableFromSourceOptionName::ExcludeColumns => "EXCLUDE COLUMNS",
1882 TableFromSourceOptionName::ExcludeConstraints => "EXCLUDE CONSTRAINTS",
1883 TableFromSourceOptionName::ExcludeAllConstraints => "EXCLUDE ALL CONSTRAINTS",
1884 TableFromSourceOptionName::ExcludeAllNotNullConstraints => {
1885 "EXCLUDE ALL NOT NULL CONSTRAINTS"
1886 }
1887 TableFromSourceOptionName::Details => "DETAILS",
1888 TableFromSourceOptionName::PartitionBy => "PARTITION BY",
1889 TableFromSourceOptionName::RetainHistory => "RETAIN HISTORY",
1890 })
1891 }
1892}
1893impl_display!(TableFromSourceOptionName);
1894
1895impl WithOptionName for TableFromSourceOptionName {
1896 fn redact_value(&self) -> bool {
1902 match self {
1903 TableFromSourceOptionName::Details
1904 | TableFromSourceOptionName::TextColumns
1905 | TableFromSourceOptionName::ExcludeColumns
1906 | TableFromSourceOptionName::ExcludeConstraints
1907 | TableFromSourceOptionName::ExcludeAllConstraints
1908 | TableFromSourceOptionName::ExcludeAllNotNullConstraints
1909 | TableFromSourceOptionName::RetainHistory => false,
1910 TableFromSourceOptionName::PartitionBy => true,
1913 }
1914 }
1915}
1916
1917#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1918pub struct TableFromSourceOption<T: AstInfo> {
1919 pub name: TableFromSourceOptionName,
1920 pub value: Option<WithOptionValue<T>>,
1921}
1922impl_display_for_with_option!(TableFromSourceOption);
1923
1924#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1933pub enum TableFromSourceColumns<T: AstInfo> {
1934 NotSpecified,
1936 Named(Vec<Ident>),
1939 Defined(Vec<ColumnDef<T>>),
1941}
1942
1943#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1945pub struct CreateTableFromSourceStatement<T: AstInfo> {
1946 pub name: UnresolvedItemName,
1947 pub columns: TableFromSourceColumns<T>,
1948 pub constraints: Vec<TableConstraint<T>>,
1949 pub if_not_exists: bool,
1950 pub source: T::ItemName,
1951 pub external_reference: Option<UnresolvedItemName>,
1952 pub with_options: Vec<TableFromSourceOption<T>>,
1953 pub include_metadata: Vec<SourceIncludeMetadata>,
1954 pub format: Option<FormatSpecifier<T>>,
1955 pub envelope: Option<SourceEnvelope>,
1956}
1957
1958impl<T: AstInfo> AstDisplay for CreateTableFromSourceStatement<T> {
1959 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1960 let Self {
1961 name,
1962 columns,
1963 constraints,
1964 source,
1965 external_reference,
1966 if_not_exists,
1967 with_options,
1968 include_metadata,
1969 format,
1970 envelope,
1971 } = self;
1972 f.write_str("CREATE TABLE ");
1973 if *if_not_exists {
1974 f.write_str("IF NOT EXISTS ");
1975 }
1976 f.write_node(name);
1977 if !matches!(columns, TableFromSourceColumns::NotSpecified) || !constraints.is_empty() {
1978 f.write_str(" (");
1979
1980 match columns {
1981 TableFromSourceColumns::NotSpecified => {}
1982 TableFromSourceColumns::Named(columns) => {
1983 f.write_node(&display::comma_separated(columns))
1984 }
1985 TableFromSourceColumns::Defined(columns) => {
1986 f.write_node(&display::comma_separated(columns))
1987 }
1988 };
1989 if !constraints.is_empty() {
1990 if !matches!(columns, TableFromSourceColumns::NotSpecified) {
1991 f.write_str(", ");
1992 }
1993 f.write_node(&display::comma_separated(constraints));
1994 }
1995 f.write_str(")");
1996 }
1997 f.write_str(" FROM SOURCE ");
1998 f.write_node(source);
1999 if let Some(external_reference) = external_reference {
2000 f.write_str(" (REFERENCE = ");
2001 f.write_node(external_reference);
2002 f.write_str(")");
2003 }
2004
2005 if let Some(format) = &format {
2006 f.write_str(" ");
2007 f.write_node(format);
2008 }
2009 if !include_metadata.is_empty() {
2010 f.write_str(" INCLUDE ");
2011 f.write_node(&display::comma_separated(include_metadata));
2012 }
2013 if let Some(envelope) = &envelope {
2014 f.write_str(" ENVELOPE ");
2015 f.write_node(envelope);
2016 }
2017 if !with_options.is_empty() {
2018 f.write_str(" WITH (");
2019 f.write_node(&display::comma_separated(with_options));
2020 f.write_str(")");
2021 }
2022 }
2023}
2024impl_display_t!(CreateTableFromSourceStatement);
2025
2026#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2028pub struct CreateIndexStatement<T: AstInfo> {
2029 pub name: Option<Ident>,
2031 pub in_cluster: Option<T::ClusterName>,
2032 pub on_name: T::ItemName,
2034 pub key_parts: Option<Vec<Expr<T>>>,
2037 pub with_options: Vec<IndexOption<T>>,
2038 pub if_not_exists: bool,
2039}
2040
2041impl<T: AstInfo> AstDisplay for CreateIndexStatement<T> {
2042 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2043 f.write_str("CREATE ");
2044 if self.key_parts.is_none() {
2045 f.write_str("DEFAULT ");
2046 }
2047 f.write_str("INDEX ");
2048 if self.if_not_exists {
2049 f.write_str("IF NOT EXISTS ");
2050 }
2051 if let Some(name) = &self.name {
2052 if name.as_str().eq_ignore_ascii_case("in") {
2059 f.write_str("\"");
2060 f.write_str(name.as_str());
2061 f.write_str("\"");
2062 } else {
2063 f.write_node(name);
2064 }
2065 f.write_str(" ");
2066 }
2067 if let Some(cluster) = &self.in_cluster {
2068 f.write_str("IN CLUSTER ");
2069 f.write_node(cluster);
2070 f.write_str(" ");
2071 }
2072 f.write_str("ON ");
2073 f.write_node(&self.on_name);
2074 if let Some(key_parts) = &self.key_parts {
2075 f.write_str(" (");
2076 f.write_node(&display::comma_separated(key_parts));
2077 f.write_str(")");
2078 }
2079 if !self.with_options.is_empty() {
2080 f.write_str(" WITH (");
2081 f.write_node(&display::comma_separated(&self.with_options));
2082 f.write_str(")");
2083 }
2084 }
2085}
2086impl_display_t!(CreateIndexStatement);
2087
2088#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2090pub enum IndexOptionName {
2091 RetainHistory,
2093}
2094
2095impl AstDisplay for IndexOptionName {
2096 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2097 match self {
2098 IndexOptionName::RetainHistory => {
2099 f.write_str("RETAIN HISTORY");
2100 }
2101 }
2102 }
2103}
2104
2105impl WithOptionName for IndexOptionName {
2106 fn redact_value(&self) -> bool {
2112 match self {
2113 IndexOptionName::RetainHistory => false,
2114 }
2115 }
2116}
2117
2118#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2119pub struct IndexOption<T: AstInfo> {
2120 pub name: IndexOptionName,
2121 pub value: Option<WithOptionValue<T>>,
2122}
2123impl_display_for_with_option!(IndexOption);
2124
2125#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2127pub struct CreateRoleStatement {
2128 pub name: Ident,
2130 pub options: Vec<RoleAttribute>,
2132}
2133
2134impl AstDisplay for CreateRoleStatement {
2135 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2136 f.write_str("CREATE ");
2137 f.write_str("ROLE ");
2138 f.write_node(&self.name);
2139 for option in &self.options {
2140 f.write_str(" ");
2141 option.fmt(f)
2142 }
2143 }
2144}
2145impl_display!(CreateRoleStatement);
2146
2147#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2149pub enum RoleAttribute {
2150 Inherit,
2152 NoInherit,
2154 Password(Option<String>),
2156 Login,
2158 NoLogin,
2159 SuperUser,
2160 NoSuperUser,
2161 CreateCluster,
2162 NoCreateCluster,
2163 CreateDB,
2164 NoCreateDB,
2165 CreateRole,
2166 NoCreateRole,
2167}
2168
2169impl AstDisplay for RoleAttribute {
2170 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2171 match self {
2172 RoleAttribute::SuperUser => f.write_str("SUPERUSER"),
2173 RoleAttribute::NoSuperUser => f.write_str("NOSUPERUSER"),
2174 RoleAttribute::Login => f.write_str("LOGIN"),
2175 RoleAttribute::NoLogin => f.write_str("NOLOGIN"),
2176 RoleAttribute::Inherit => f.write_str("INHERIT"),
2177 RoleAttribute::NoInherit => f.write_str("NOINHERIT"),
2178 RoleAttribute::CreateCluster => f.write_str("CREATECLUSTER"),
2179 RoleAttribute::NoCreateCluster => f.write_str("NOCREATECLUSTER"),
2180 RoleAttribute::CreateDB => f.write_str("CREATEDB"),
2181 RoleAttribute::NoCreateDB => f.write_str("NOCREATEDB"),
2182 RoleAttribute::CreateRole => f.write_str("CREATEROLE"),
2183 RoleAttribute::NoCreateRole => f.write_str("NOCREATEROLE"),
2184 RoleAttribute::Password(None) => f.write_str("PASSWORD NULL"),
2190 RoleAttribute::Password(Some(_)) => f.write_str("PASSWORD '<REDACTED>'"),
2191 }
2192 }
2193}
2194impl_display!(RoleAttribute);
2195
2196#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2198pub enum SetRoleVar {
2199 Set { name: Ident, value: SetVariableTo },
2201 Reset { name: Ident },
2203}
2204
2205impl AstDisplay for SetRoleVar {
2206 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2207 match self {
2208 SetRoleVar::Set { name, value } => {
2209 f.write_str("SET ");
2210 f.write_node(name);
2211 f.write_str(" = ");
2212 f.write_node(value);
2213 }
2214 SetRoleVar::Reset { name } => {
2215 f.write_str("RESET ");
2216 f.write_node(name);
2217 }
2218 }
2219 }
2220}
2221impl_display!(SetRoleVar);
2222
2223#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2225pub struct AlterNetworkPolicyStatement<T: AstInfo> {
2226 pub name: Ident,
2228 pub options: Vec<NetworkPolicyOption<T>>,
2230}
2231
2232impl<T: AstInfo> AstDisplay for AlterNetworkPolicyStatement<T> {
2233 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2234 f.write_str("ALTER ");
2235 f.write_str("NETWORK POLICY ");
2236 f.write_node(&self.name);
2237 f.write_str(" SET (");
2238 f.write_node(&display::comma_separated(&self.options));
2239 f.write_str(" )");
2240 }
2241}
2242impl_display_t!(AlterNetworkPolicyStatement);
2243
2244#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2246pub struct CreateNetworkPolicyStatement<T: AstInfo> {
2247 pub name: Ident,
2249 pub options: Vec<NetworkPolicyOption<T>>,
2251}
2252
2253impl<T: AstInfo> AstDisplay for CreateNetworkPolicyStatement<T> {
2254 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2255 f.write_str("CREATE ");
2256 f.write_str("NETWORK POLICY ");
2257 f.write_node(&self.name);
2258 f.write_str(" (");
2259 f.write_node(&display::comma_separated(&self.options));
2260 f.write_str(" )");
2261 }
2262}
2263impl_display_t!(CreateNetworkPolicyStatement);
2264
2265#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2266pub struct NetworkPolicyOption<T: AstInfo> {
2267 pub name: NetworkPolicyOptionName,
2268 pub value: Option<WithOptionValue<T>>,
2269}
2270
2271#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2272pub enum NetworkPolicyOptionName {
2273 Rules,
2274}
2275
2276impl WithOptionName for NetworkPolicyOptionName {
2277 fn redact_value(&self) -> bool {
2283 match self {
2284 NetworkPolicyOptionName::Rules => false,
2285 }
2286 }
2287}
2288
2289impl AstDisplay for NetworkPolicyOptionName {
2290 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2291 match self {
2292 NetworkPolicyOptionName::Rules => f.write_str("RULES"),
2293 }
2294 }
2295}
2296impl_display_for_with_option!(NetworkPolicyOption);
2297
2298#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2299pub struct NetworkPolicyRuleDefinition<T: AstInfo> {
2300 pub name: Ident,
2301 pub options: Vec<NetworkPolicyRuleOption<T>>,
2302}
2303
2304impl<T: AstInfo> AstDisplay for NetworkPolicyRuleDefinition<T> {
2305 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2306 f.write_node(&self.name);
2307 f.write_str(" (");
2308 f.write_node(&display::comma_separated(&self.options));
2309 f.write_str(" )");
2310 }
2311}
2312
2313#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2314pub struct NetworkPolicyRuleOption<T: AstInfo> {
2315 pub name: NetworkPolicyRuleOptionName,
2316 pub value: Option<WithOptionValue<T>>,
2317}
2318
2319#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2320pub enum NetworkPolicyRuleOptionName {
2321 Direction,
2322 Action,
2323 Address,
2324}
2325
2326impl WithOptionName for NetworkPolicyRuleOptionName {
2327 fn redact_value(&self) -> bool {
2333 match self {
2334 NetworkPolicyRuleOptionName::Direction
2335 | NetworkPolicyRuleOptionName::Action
2336 | NetworkPolicyRuleOptionName::Address => false,
2337 }
2338 }
2339}
2340
2341impl AstDisplay for NetworkPolicyRuleOptionName {
2342 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2343 match self {
2344 NetworkPolicyRuleOptionName::Direction => f.write_str("DIRECTION"),
2345 NetworkPolicyRuleOptionName::Action => f.write_str("ACTION"),
2346 NetworkPolicyRuleOptionName::Address => f.write_str("ADDRESS"),
2347 }
2348 }
2349}
2350
2351impl_display_for_with_option!(NetworkPolicyRuleOption);
2352
2353#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2355pub struct CreateSecretStatement<T: AstInfo> {
2356 pub name: UnresolvedItemName,
2357 pub if_not_exists: bool,
2358 pub value: Expr<T>,
2359}
2360
2361impl<T: AstInfo> AstDisplay for CreateSecretStatement<T> {
2362 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2363 f.write_str("CREATE SECRET ");
2364 if self.if_not_exists {
2365 f.write_str("IF NOT EXISTS ");
2366 }
2367 f.write_node(&self.name);
2368 f.write_str(" AS ");
2369
2370 if f.redacted() {
2371 f.write_str("'<REDACTED>'");
2372 } else {
2373 f.write_node(&self.value);
2374 }
2375 }
2376}
2377impl_display_t!(CreateSecretStatement);
2378
2379#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2381pub struct CreateTypeStatement<T: AstInfo> {
2382 pub name: UnresolvedItemName,
2384 pub as_type: CreateTypeAs<T>,
2386}
2387
2388impl<T: AstInfo> AstDisplay for CreateTypeStatement<T> {
2389 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2390 f.write_str("CREATE TYPE ");
2391 f.write_node(&self.name);
2392 f.write_str(" AS ");
2393 match &self.as_type {
2394 CreateTypeAs::List { options } => {
2395 f.write_str(&self.as_type);
2396 f.write_str("(");
2397 if !options.is_empty() {
2398 f.write_node(&display::comma_separated(options));
2399 }
2400 f.write_str(")");
2401 }
2402 CreateTypeAs::Map { options } => {
2403 f.write_str(&self.as_type);
2404 f.write_str("(");
2405 if !options.is_empty() {
2406 f.write_node(&display::comma_separated(options));
2407 }
2408 f.write_str(")");
2409 }
2410 CreateTypeAs::Record { column_defs } => {
2411 f.write_str("(");
2412 if !column_defs.is_empty() {
2413 f.write_node(&display::comma_separated(column_defs));
2414 }
2415 f.write_str(")");
2416 }
2417 };
2418 }
2419}
2420impl_display_t!(CreateTypeStatement);
2421
2422#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2423pub enum ClusterOptionName {
2424 AutoScalingStrategy,
2426 AvailabilityZones,
2428 Disk,
2430 ExperimentalArrangementCompression,
2432 IntrospectionInterval,
2434 IntrospectionDebugging,
2436 Managed,
2438 Replicas,
2440 ReplicationFactor,
2442 Size,
2444 Schedule,
2446 WorkloadClass,
2448}
2449
2450impl AstDisplay for ClusterOptionName {
2451 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2452 match self {
2453 ClusterOptionName::AutoScalingStrategy => f.write_str("AUTO SCALING STRATEGY"),
2454 ClusterOptionName::AvailabilityZones => f.write_str("AVAILABILITY ZONES"),
2455 ClusterOptionName::Disk => f.write_str("DISK"),
2456 ClusterOptionName::ExperimentalArrangementCompression => {
2457 f.write_str("EXPERIMENTAL ARRANGEMENT COMPRESSION")
2458 }
2459 ClusterOptionName::IntrospectionDebugging => f.write_str("INTROSPECTION DEBUGGING"),
2460 ClusterOptionName::IntrospectionInterval => f.write_str("INTROSPECTION INTERVAL"),
2461 ClusterOptionName::Managed => f.write_str("MANAGED"),
2462 ClusterOptionName::Replicas => f.write_str("REPLICAS"),
2463 ClusterOptionName::ReplicationFactor => f.write_str("REPLICATION FACTOR"),
2464 ClusterOptionName::Size => f.write_str("SIZE"),
2465 ClusterOptionName::Schedule => f.write_str("SCHEDULE"),
2466 ClusterOptionName::WorkloadClass => f.write_str("WORKLOAD CLASS"),
2467 }
2468 }
2469}
2470
2471impl WithOptionName for ClusterOptionName {
2472 fn redact_value(&self) -> bool {
2478 match self {
2479 ClusterOptionName::AutoScalingStrategy
2480 | ClusterOptionName::AvailabilityZones
2481 | ClusterOptionName::Disk
2482 | ClusterOptionName::ExperimentalArrangementCompression
2483 | ClusterOptionName::IntrospectionDebugging
2484 | ClusterOptionName::IntrospectionInterval
2485 | ClusterOptionName::Managed
2486 | ClusterOptionName::Replicas
2487 | ClusterOptionName::ReplicationFactor
2488 | ClusterOptionName::Size
2489 | ClusterOptionName::Schedule
2490 | ClusterOptionName::WorkloadClass => false,
2491 }
2492 }
2493}
2494
2495#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2496pub struct ClusterOption<T: AstInfo> {
2498 pub name: ClusterOptionName,
2499 pub value: Option<WithOptionValue<T>>,
2500}
2501impl_display_for_with_option!(ClusterOption);
2502
2503#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2504pub enum ClusterAlterUntilReadyOptionName {
2505 Timeout,
2506 OnTimeout,
2507}
2508
2509impl AstDisplay for ClusterAlterUntilReadyOptionName {
2510 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2511 match self {
2512 Self::Timeout => f.write_str("TIMEOUT"),
2513 Self::OnTimeout => f.write_str("ON TIMEOUT"),
2514 }
2515 }
2516}
2517
2518impl WithOptionName for ClusterAlterUntilReadyOptionName {
2519 fn redact_value(&self) -> bool {
2525 match self {
2526 ClusterAlterUntilReadyOptionName::Timeout
2527 | ClusterAlterUntilReadyOptionName::OnTimeout => false,
2528 }
2529 }
2530}
2531
2532#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2533pub struct ClusterAlterUntilReadyOption<T: AstInfo> {
2534 pub name: ClusterAlterUntilReadyOptionName,
2535 pub value: Option<WithOptionValue<T>>,
2536}
2537impl_display_for_with_option!(ClusterAlterUntilReadyOption);
2538
2539#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2540pub enum ClusterAlterOptionName {
2541 Wait,
2542}
2543
2544impl AstDisplay for ClusterAlterOptionName {
2545 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2546 match self {
2547 ClusterAlterOptionName::Wait => f.write_str("WAIT"),
2548 }
2549 }
2550}
2551
2552impl WithOptionName for ClusterAlterOptionName {
2553 fn redact_value(&self) -> bool {
2559 match self {
2560 ClusterAlterOptionName::Wait => false,
2561 }
2562 }
2563}
2564
2565#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2566pub enum ClusterAlterOptionValue<T: AstInfo> {
2567 For(Value),
2568 UntilReady(Vec<ClusterAlterUntilReadyOption<T>>),
2569}
2570
2571impl<T: AstInfo> AstDisplay for ClusterAlterOptionValue<T> {
2572 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2573 match self {
2574 ClusterAlterOptionValue::For(duration) => {
2575 f.write_str("FOR ");
2576 f.write_node(duration);
2577 }
2578 ClusterAlterOptionValue::UntilReady(options) => {
2579 f.write_str("UNTIL READY (");
2580 f.write_node(&display::comma_separated(options));
2581 f.write_str(")");
2582 }
2583 }
2584 }
2585}
2586
2587#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2588pub struct ClusterAlterOption<T: AstInfo> {
2590 pub name: ClusterAlterOptionName,
2591 pub value: Option<WithOptionValue<T>>,
2592}
2593
2594impl_display_for_with_option!(ClusterAlterOption);
2595
2596#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2599pub enum ClusterFeatureName {
2600 ReoptimizeImportedViews,
2601 EnableNewOuterJoinLowering,
2602 EnableEagerDeltaJoins,
2603 EnableVariadicLeftJoinLowering,
2604 EnableLetrecFixpointAnalysis,
2605 EnableJoinPrioritizeArranged,
2606 EnableProjectionPushdownAfterRelationCse,
2607 EnableUnionCancellationAfterRelationCse,
2608}
2609
2610impl WithOptionName for ClusterFeatureName {
2611 fn redact_value(&self) -> bool {
2617 match self {
2618 Self::ReoptimizeImportedViews
2619 | Self::EnableNewOuterJoinLowering
2620 | Self::EnableEagerDeltaJoins
2621 | Self::EnableVariadicLeftJoinLowering
2622 | Self::EnableLetrecFixpointAnalysis
2623 | Self::EnableJoinPrioritizeArranged
2624 | Self::EnableProjectionPushdownAfterRelationCse
2625 | Self::EnableUnionCancellationAfterRelationCse => false,
2626 }
2627 }
2628}
2629
2630#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2631pub struct ClusterFeature<T: AstInfo> {
2632 pub name: ClusterFeatureName,
2633 pub value: Option<WithOptionValue<T>>,
2634}
2635impl_display_for_with_option!(ClusterFeature);
2636
2637#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2639pub struct CreateClusterStatement<T: AstInfo> {
2640 pub name: Ident,
2642 pub options: Vec<ClusterOption<T>>,
2644 pub features: Vec<ClusterFeature<T>>,
2646 pub if_not_exists: bool,
2647}
2648
2649impl<T: AstInfo> AstDisplay for CreateClusterStatement<T> {
2650 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2651 f.write_str("CREATE CLUSTER ");
2652 if self.if_not_exists {
2653 f.write_str("IF NOT EXISTS ");
2654 }
2655 f.write_node(&self.name);
2656 if !self.options.is_empty() {
2657 f.write_str(" (");
2658 f.write_node(&display::comma_separated(&self.options));
2659 f.write_str(")");
2660 }
2661 if !self.features.is_empty() {
2662 f.write_str(" FEATURES (");
2663 f.write_node(&display::comma_separated(&self.features));
2664 f.write_str(")");
2665 }
2666 }
2667}
2668impl_display_t!(CreateClusterStatement);
2669
2670#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2671pub struct ReplicaDefinition<T: AstInfo> {
2672 pub name: Ident,
2674 pub options: Vec<ReplicaOption<T>>,
2676}
2677
2678impl<T: AstInfo> AstDisplay for ReplicaDefinition<T> {
2681 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2682 f.write_node(&self.name);
2683 f.write_str(" (");
2684 f.write_node(&display::comma_separated(&self.options));
2685 f.write_str(")");
2686 }
2687}
2688impl_display_t!(ReplicaDefinition);
2689
2690#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2691pub enum AlterClusterAction<T: AstInfo> {
2692 SetOptions {
2693 options: Vec<ClusterOption<T>>,
2694 with_options: Vec<ClusterAlterOption<T>>,
2695 },
2696 ResetOptions(Vec<ClusterOptionName>),
2697}
2698
2699#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2701pub struct AlterClusterStatement<T: AstInfo> {
2702 pub if_exists: bool,
2704 pub name: Ident,
2706 pub action: AlterClusterAction<T>,
2708}
2709
2710impl<T: AstInfo> AstDisplay for AlterClusterStatement<T> {
2711 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2712 f.write_str("ALTER CLUSTER ");
2713 if self.if_exists {
2714 f.write_str("IF EXISTS ");
2715 }
2716 f.write_node(&self.name);
2717 f.write_str(" ");
2718 match &self.action {
2719 AlterClusterAction::SetOptions {
2720 options,
2721 with_options,
2722 } => {
2723 f.write_str("SET (");
2724 f.write_node(&display::comma_separated(options));
2725 f.write_str(")");
2726 if !with_options.is_empty() {
2727 f.write_str(" WITH (");
2728 f.write_node(&display::comma_separated(with_options));
2729 f.write_str(")");
2730 }
2731 }
2732 AlterClusterAction::ResetOptions(options) => {
2733 f.write_str("RESET (");
2734 f.write_node(&display::comma_separated(options));
2735 f.write_str(")");
2736 }
2737 }
2738 }
2739}
2740impl_display_t!(AlterClusterStatement);
2741
2742#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2744pub struct CreateClusterReplicaStatement<T: AstInfo> {
2745 pub of_cluster: Ident,
2747 pub definition: ReplicaDefinition<T>,
2749 pub if_not_exists: bool,
2750}
2751
2752impl<T: AstInfo> AstDisplay for CreateClusterReplicaStatement<T> {
2753 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2754 f.write_str("CREATE CLUSTER REPLICA ");
2755 if self.if_not_exists {
2756 f.write_str("IF NOT EXISTS ");
2757 }
2758 f.write_node(&self.of_cluster);
2759 f.write_str(".");
2760 f.write_node(&self.definition.name);
2761 f.write_str(" (");
2762 f.write_node(&display::comma_separated(&self.definition.options));
2763 f.write_str(")");
2764 }
2765}
2766impl_display_t!(CreateClusterReplicaStatement);
2767
2768#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2769pub enum ReplicaOptionName {
2770 BilledAs,
2772 Size,
2774 AvailabilityZone,
2776 StorageAddresses,
2778 StoragectlAddresses,
2780 ComputectlAddresses,
2782 ComputeAddresses,
2784 Workers,
2786 Internal,
2788 IntrospectionInterval,
2790 IntrospectionDebugging,
2792 Disk,
2794 ExperimentalArrangementCompression,
2796}
2797
2798impl AstDisplay for ReplicaOptionName {
2799 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2800 match self {
2801 ReplicaOptionName::BilledAs => f.write_str("BILLED AS"),
2802 ReplicaOptionName::Size => f.write_str("SIZE"),
2803 ReplicaOptionName::AvailabilityZone => f.write_str("AVAILABILITY ZONE"),
2804 ReplicaOptionName::StorageAddresses => f.write_str("STORAGE ADDRESSES"),
2805 ReplicaOptionName::StoragectlAddresses => f.write_str("STORAGECTL ADDRESSES"),
2806 ReplicaOptionName::ComputectlAddresses => f.write_str("COMPUTECTL ADDRESSES"),
2807 ReplicaOptionName::ComputeAddresses => f.write_str("COMPUTE ADDRESSES"),
2808 ReplicaOptionName::Workers => f.write_str("WORKERS"),
2809 ReplicaOptionName::Internal => f.write_str("INTERNAL"),
2810 ReplicaOptionName::IntrospectionInterval => f.write_str("INTROSPECTION INTERVAL"),
2811 ReplicaOptionName::IntrospectionDebugging => f.write_str("INTROSPECTION DEBUGGING"),
2812 ReplicaOptionName::Disk => f.write_str("DISK"),
2813 ReplicaOptionName::ExperimentalArrangementCompression => {
2814 f.write_str("EXPERIMENTAL ARRANGEMENT COMPRESSION")
2815 }
2816 }
2817 }
2818}
2819
2820impl WithOptionName for ReplicaOptionName {
2821 fn redact_value(&self) -> bool {
2827 match self {
2828 ReplicaOptionName::BilledAs
2829 | ReplicaOptionName::Size
2830 | ReplicaOptionName::AvailabilityZone
2831 | ReplicaOptionName::StorageAddresses
2832 | ReplicaOptionName::StoragectlAddresses
2833 | ReplicaOptionName::ComputectlAddresses
2834 | ReplicaOptionName::ComputeAddresses
2835 | ReplicaOptionName::Workers
2836 | ReplicaOptionName::Internal
2837 | ReplicaOptionName::IntrospectionInterval
2838 | ReplicaOptionName::IntrospectionDebugging
2839 | ReplicaOptionName::Disk
2840 | ReplicaOptionName::ExperimentalArrangementCompression => false,
2841 }
2842 }
2843}
2844
2845#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2846pub struct ReplicaOption<T: AstInfo> {
2848 pub name: ReplicaOptionName,
2849 pub value: Option<WithOptionValue<T>>,
2850}
2851impl_display_for_with_option!(ReplicaOption);
2852
2853#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2855pub enum CreateTypeAs<T: AstInfo> {
2856 List {
2857 options: Vec<CreateTypeListOption<T>>,
2858 },
2859 Map {
2860 options: Vec<CreateTypeMapOption<T>>,
2861 },
2862 Record {
2863 column_defs: Vec<ColumnDef<T>>,
2864 },
2865}
2866
2867impl<T: AstInfo> AstDisplay for CreateTypeAs<T> {
2868 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2869 match self {
2870 CreateTypeAs::List { .. } => f.write_str("LIST "),
2871 CreateTypeAs::Map { .. } => f.write_str("MAP "),
2872 CreateTypeAs::Record { .. } => f.write_str("RECORD "),
2873 }
2874 }
2875}
2876impl_display_t!(CreateTypeAs);
2877
2878#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2879pub enum CreateTypeListOptionName {
2880 ElementType,
2881}
2882
2883impl AstDisplay for CreateTypeListOptionName {
2884 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2885 f.write_str(match self {
2886 CreateTypeListOptionName::ElementType => "ELEMENT TYPE",
2887 })
2888 }
2889}
2890
2891impl WithOptionName for CreateTypeListOptionName {
2892 fn redact_value(&self) -> bool {
2898 match self {
2899 CreateTypeListOptionName::ElementType => false,
2900 }
2901 }
2902}
2903
2904#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2905pub struct CreateTypeListOption<T: AstInfo> {
2906 pub name: CreateTypeListOptionName,
2907 pub value: Option<WithOptionValue<T>>,
2908}
2909impl_display_for_with_option!(CreateTypeListOption);
2910
2911#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2912pub enum CreateTypeMapOptionName {
2913 KeyType,
2914 ValueType,
2915}
2916
2917impl AstDisplay for CreateTypeMapOptionName {
2918 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2919 f.write_str(match self {
2920 CreateTypeMapOptionName::KeyType => "KEY TYPE",
2921 CreateTypeMapOptionName::ValueType => "VALUE TYPE",
2922 })
2923 }
2924}
2925
2926impl WithOptionName for CreateTypeMapOptionName {
2927 fn redact_value(&self) -> bool {
2933 match self {
2934 CreateTypeMapOptionName::KeyType | CreateTypeMapOptionName::ValueType => false,
2935 }
2936 }
2937}
2938
2939#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2940pub struct CreateTypeMapOption<T: AstInfo> {
2941 pub name: CreateTypeMapOptionName,
2942 pub value: Option<WithOptionValue<T>>,
2943}
2944impl_display_for_with_option!(CreateTypeMapOption);
2945
2946#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2948pub struct AlterOwnerStatement<T: AstInfo> {
2949 pub object_type: ObjectType,
2950 pub if_exists: bool,
2951 pub name: UnresolvedObjectName,
2952 pub new_owner: T::RoleName,
2953}
2954
2955impl<T: AstInfo> AstDisplay for AlterOwnerStatement<T> {
2956 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2957 f.write_str("ALTER ");
2958 f.write_node(&self.object_type);
2959 f.write_str(" ");
2960 if self.if_exists {
2961 f.write_str("IF EXISTS ");
2962 }
2963 f.write_node(&self.name);
2964 f.write_str(" OWNER TO ");
2965 f.write_node(&self.new_owner);
2966 }
2967}
2968impl_display_t!(AlterOwnerStatement);
2969
2970#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2972pub struct AlterObjectRenameStatement {
2973 pub object_type: ObjectType,
2974 pub if_exists: bool,
2975 pub name: UnresolvedObjectName,
2976 pub to_item_name: Ident,
2977}
2978
2979impl AstDisplay for AlterObjectRenameStatement {
2980 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2981 f.write_str("ALTER ");
2982 f.write_node(&self.object_type);
2983 f.write_str(" ");
2984 if self.if_exists {
2985 f.write_str("IF EXISTS ");
2986 }
2987 f.write_node(&self.name);
2988 f.write_str(" RENAME TO ");
2989 f.write_node(&self.to_item_name);
2990 }
2991}
2992impl_display!(AlterObjectRenameStatement);
2993
2994#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2996pub struct AlterRetainHistoryStatement<T: AstInfo> {
2997 pub object_type: ObjectType,
2998 pub if_exists: bool,
2999 pub name: UnresolvedObjectName,
3000 pub history: Option<WithOptionValue<T>>,
3001}
3002
3003impl<T: AstInfo> AstDisplay for AlterRetainHistoryStatement<T> {
3004 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3005 f.write_str("ALTER ");
3006 f.write_node(&self.object_type);
3007 f.write_str(" ");
3008 if self.if_exists {
3009 f.write_str("IF EXISTS ");
3010 }
3011 f.write_node(&self.name);
3012 if let Some(history) = &self.history {
3013 f.write_str(" SET (RETAIN HISTORY ");
3014 f.write_node(history);
3015 } else {
3016 f.write_str(" RESET (RETAIN HISTORY");
3017 }
3018 f.write_str(")");
3019 }
3020}
3021impl_display_t!(AlterRetainHistoryStatement);
3022
3023#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3025pub struct AlterObjectSwapStatement {
3026 pub object_type: ObjectType,
3027 pub if_exists: bool,
3028 pub name_a: UnresolvedObjectName,
3029 pub name_b: Ident,
3030}
3031
3032impl AstDisplay for AlterObjectSwapStatement {
3033 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3034 f.write_str("ALTER ");
3035
3036 f.write_node(&self.object_type);
3037 f.write_str(" ");
3038 if self.if_exists {
3039 f.write_str("IF EXISTS ");
3040 }
3041 f.write_node(&self.name_a);
3042
3043 f.write_str(" SWAP WITH ");
3044 f.write_node(&self.name_b);
3045 }
3046}
3047impl_display!(AlterObjectSwapStatement);
3048
3049#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3050pub enum AlterIndexAction<T: AstInfo> {
3051 SetOptions(Vec<IndexOption<T>>),
3052 ResetOptions(Vec<IndexOptionName>),
3053}
3054
3055#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3057pub struct AlterIndexStatement<T: AstInfo> {
3058 pub index_name: UnresolvedItemName,
3059 pub if_exists: bool,
3060 pub action: AlterIndexAction<T>,
3061}
3062
3063impl<T: AstInfo> AstDisplay for AlterIndexStatement<T> {
3064 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3065 f.write_str("ALTER INDEX ");
3066 if self.if_exists {
3067 f.write_str("IF EXISTS ");
3068 }
3069 f.write_node(&self.index_name);
3070 f.write_str(" ");
3071
3072 match &self.action {
3073 AlterIndexAction::SetOptions(options) => {
3074 f.write_str("SET (");
3075 f.write_node(&display::comma_separated(options));
3076 f.write_str(")");
3077 }
3078 AlterIndexAction::ResetOptions(options) => {
3079 f.write_str("RESET (");
3080 f.write_node(&display::comma_separated(options));
3081 f.write_str(")");
3082 }
3083 }
3084 }
3085}
3086
3087impl_display_t!(AlterIndexStatement);
3088
3089#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3090pub enum AlterSinkAction<T: AstInfo> {
3091 SetOptions(Vec<CreateSinkOption<T>>),
3092 ResetOptions(Vec<CreateSinkOptionName>),
3093 ChangeRelation(T::ItemName),
3094}
3095
3096#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3097pub struct AlterSinkStatement<T: AstInfo> {
3098 pub sink_name: UnresolvedItemName,
3099 pub if_exists: bool,
3100 pub action: AlterSinkAction<T>,
3101}
3102
3103impl<T: AstInfo> AstDisplay for AlterSinkStatement<T> {
3104 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3105 f.write_str("ALTER SINK ");
3106 if self.if_exists {
3107 f.write_str("IF EXISTS ");
3108 }
3109 f.write_node(&self.sink_name);
3110 f.write_str(" ");
3111
3112 match &self.action {
3113 AlterSinkAction::ChangeRelation(from) => {
3114 f.write_str("SET FROM ");
3115 f.write_node(from);
3116 }
3117 AlterSinkAction::SetOptions(options) => {
3118 f.write_str("SET (");
3119 f.write_node(&display::comma_separated(options));
3120 f.write_str(")");
3121 }
3122 AlterSinkAction::ResetOptions(options) => {
3123 f.write_str("RESET (");
3124 f.write_node(&display::comma_separated(options));
3125 f.write_str(")");
3126 }
3127 }
3128 }
3129}
3130
3131#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3132pub enum AlterSourceAddSubsourceOptionName {
3133 TextColumns,
3135 ExcludeColumns,
3137 Details,
3142}
3143
3144impl AstDisplay for AlterSourceAddSubsourceOptionName {
3145 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3146 f.write_str(match self {
3147 AlterSourceAddSubsourceOptionName::TextColumns => "TEXT COLUMNS",
3148 AlterSourceAddSubsourceOptionName::ExcludeColumns => "EXCLUDE COLUMNS",
3149 AlterSourceAddSubsourceOptionName::Details => "DETAILS",
3150 })
3151 }
3152}
3153impl_display!(AlterSourceAddSubsourceOptionName);
3154
3155impl WithOptionName for AlterSourceAddSubsourceOptionName {
3156 fn redact_value(&self) -> bool {
3162 match self {
3163 AlterSourceAddSubsourceOptionName::Details
3164 | AlterSourceAddSubsourceOptionName::TextColumns
3165 | AlterSourceAddSubsourceOptionName::ExcludeColumns => false,
3166 }
3167 }
3168}
3169
3170#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3171pub struct AlterSourceAddSubsourceOption<T: AstInfo> {
3173 pub name: AlterSourceAddSubsourceOptionName,
3174 pub value: Option<WithOptionValue<T>>,
3175}
3176impl_display_for_with_option!(AlterSourceAddSubsourceOption);
3177impl_display_t!(AlterSourceAddSubsourceOption);
3178
3179#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3180pub enum AlterSourceAction<T: AstInfo> {
3181 SetOptions(Vec<CreateSourceOption<T>>),
3182 ResetOptions(Vec<CreateSourceOptionName>),
3183 AddSubsources {
3184 external_references: Vec<ExternalReferenceExport>,
3185 options: Vec<AlterSourceAddSubsourceOption<T>>,
3186 },
3187 DropSubsources {
3188 if_exists: bool,
3189 cascade: bool,
3190 names: Vec<UnresolvedItemName>,
3191 },
3192 RefreshReferences,
3193}
3194
3195impl<T: AstInfo> AstDisplay for AlterSourceAction<T> {
3196 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3197 where
3198 W: fmt::Write,
3199 {
3200 match &self {
3201 AlterSourceAction::SetOptions(options) => {
3202 f.write_str("SET (");
3203 f.write_node(&display::comma_separated(options));
3204 f.write_str(")");
3205 }
3206 AlterSourceAction::ResetOptions(options) => {
3207 f.write_str("RESET (");
3208 f.write_node(&display::comma_separated(options));
3209 f.write_str(")");
3210 }
3211 AlterSourceAction::DropSubsources {
3212 if_exists,
3213 cascade,
3214 names,
3215 } => {
3216 f.write_str("DROP SUBSOURCE ");
3217 if *if_exists {
3218 f.write_str("IF EXISTS ");
3219 }
3220
3221 f.write_node(&display::comma_separated(names));
3222
3223 if *cascade {
3224 f.write_str(" CASCADE");
3225 }
3226 }
3227 AlterSourceAction::AddSubsources {
3228 external_references: subsources,
3229 options,
3230 } => {
3231 f.write_str("ADD SUBSOURCE ");
3232
3233 f.write_node(&display::comma_separated(subsources));
3234
3235 if !options.is_empty() {
3236 f.write_str(" WITH (");
3237 f.write_node(&display::comma_separated(options));
3238 f.write_str(")");
3239 }
3240 }
3241 AlterSourceAction::RefreshReferences => {
3242 f.write_str("REFRESH REFERENCES");
3243 }
3244 }
3245 }
3246}
3247
3248#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3249pub struct AlterSourceStatement<T: AstInfo> {
3250 pub source_name: UnresolvedItemName,
3251 pub if_exists: bool,
3252 pub action: AlterSourceAction<T>,
3253}
3254
3255impl<T: AstInfo> AstDisplay for AlterSourceStatement<T> {
3256 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3257 f.write_str("ALTER SOURCE ");
3258 if self.if_exists {
3259 f.write_str("IF EXISTS ");
3260 }
3261 f.write_node(&self.source_name);
3262 f.write_str(" ");
3263 f.write_node(&self.action)
3264 }
3265}
3266
3267impl_display_t!(AlterSourceStatement);
3268
3269#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3271pub struct AlterSecretStatement<T: AstInfo> {
3272 pub name: UnresolvedItemName,
3273 pub if_exists: bool,
3274 pub value: Expr<T>,
3275}
3276
3277impl<T: AstInfo> AstDisplay for AlterSecretStatement<T> {
3278 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3279 f.write_str("ALTER SECRET ");
3280 if self.if_exists {
3281 f.write_str("IF EXISTS ");
3282 }
3283 f.write_node(&self.name);
3284 f.write_str(" AS ");
3285
3286 if f.redacted() {
3287 f.write_str("'<REDACTED>'");
3288 } else {
3289 f.write_node(&self.value);
3290 }
3291 }
3292}
3293
3294impl_display_t!(AlterSecretStatement);
3295
3296#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3297pub enum AlterConnectionAction<T: AstInfo> {
3298 RotateKeys,
3299 SetOption(ConnectionOption<T>),
3300 DropOption(ConnectionOptionName),
3301}
3302
3303impl<T: AstInfo> AstDisplay for AlterConnectionAction<T> {
3304 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3305 match self {
3306 AlterConnectionAction::RotateKeys => f.write_str("ROTATE KEYS"),
3307 AlterConnectionAction::SetOption(option) => {
3308 f.write_str("SET (");
3309 f.write_node(option);
3310 f.write_str(")");
3311 }
3312 AlterConnectionAction::DropOption(option) => {
3313 f.write_str("DROP (");
3314 f.write_node(option);
3315 f.write_str(")");
3316 }
3317 }
3318 }
3319}
3320impl_display_t!(AlterConnectionAction);
3321
3322#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3323pub enum AlterConnectionOptionName {
3324 Validate,
3325}
3326
3327impl AstDisplay for AlterConnectionOptionName {
3328 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3329 f.write_str(match self {
3330 AlterConnectionOptionName::Validate => "VALIDATE",
3331 })
3332 }
3333}
3334impl_display!(AlterConnectionOptionName);
3335
3336impl WithOptionName for AlterConnectionOptionName {
3337 fn redact_value(&self) -> bool {
3343 match self {
3344 AlterConnectionOptionName::Validate => false,
3345 }
3346 }
3347}
3348
3349#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3350pub struct AlterConnectionOption<T: AstInfo> {
3352 pub name: AlterConnectionOptionName,
3353 pub value: Option<WithOptionValue<T>>,
3354}
3355impl_display_for_with_option!(AlterConnectionOption);
3356impl_display_t!(AlterConnectionOption);
3357
3358#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3360pub struct AlterConnectionStatement<T: AstInfo> {
3361 pub name: UnresolvedItemName,
3362 pub if_exists: bool,
3363 pub actions: Vec<AlterConnectionAction<T>>,
3364 pub with_options: Vec<AlterConnectionOption<T>>,
3365}
3366
3367impl<T: AstInfo> AstDisplay for AlterConnectionStatement<T> {
3368 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3369 f.write_str("ALTER CONNECTION ");
3370 if self.if_exists {
3371 f.write_str("IF EXISTS ");
3372 }
3373 f.write_node(&self.name);
3374 f.write_str(" ");
3375 f.write_node(&display::comma_separated(&self.actions));
3376
3377 if !self.with_options.is_empty() {
3378 f.write_str(" WITH (");
3379 f.write_node(&display::comma_separated(&self.with_options));
3380 f.write_str(")");
3381 }
3382 }
3383}
3384
3385impl_display_t!(AlterConnectionStatement);
3386
3387#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3389pub struct AlterRoleStatement<T: AstInfo> {
3390 pub name: T::RoleName,
3392 pub option: AlterRoleOption,
3394}
3395
3396impl<T: AstInfo> AstDisplay for AlterRoleStatement<T> {
3397 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3398 f.write_str("ALTER ROLE ");
3399 f.write_node(&self.name);
3400 f.write_node(&self.option);
3401 }
3402}
3403impl_display_t!(AlterRoleStatement);
3404
3405#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3407pub enum AlterRoleOption {
3408 Attributes(Vec<RoleAttribute>),
3410 Variable(SetRoleVar),
3412}
3413
3414impl AstDisplay for AlterRoleOption {
3415 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3416 match self {
3417 AlterRoleOption::Attributes(attrs) => {
3418 for attr in attrs {
3419 f.write_str(" ");
3420 attr.fmt(f)
3421 }
3422 }
3423 AlterRoleOption::Variable(var) => {
3424 f.write_str(" ");
3425 f.write_node(var);
3426 }
3427 }
3428 }
3429}
3430impl_display!(AlterRoleOption);
3431
3432#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3434pub struct AlterTableAddColumnStatement<T: AstInfo> {
3435 pub if_exists: bool,
3436 pub name: UnresolvedItemName,
3437 pub if_col_not_exist: bool,
3438 pub column_name: Ident,
3439 pub data_type: T::DataType,
3440}
3441
3442impl<T: AstInfo> AstDisplay for AlterTableAddColumnStatement<T> {
3443 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3444 where
3445 W: fmt::Write,
3446 {
3447 f.write_str("ALTER TABLE ");
3448 if self.if_exists {
3449 f.write_str("IF EXISTS ");
3450 }
3451 f.write_node(&self.name);
3452
3453 f.write_str(" ADD COLUMN ");
3454 if self.if_col_not_exist {
3455 f.write_str("IF NOT EXISTS ");
3456 }
3457
3458 f.write_node(&self.column_name);
3459 f.write_str(" ");
3460 f.write_node(&self.data_type);
3461 }
3462}
3463
3464impl_display_t!(AlterTableAddColumnStatement);
3465
3466#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3468pub struct AlterMaterializedViewApplyReplacementStatement {
3469 pub if_exists: bool,
3470 pub name: UnresolvedItemName,
3471 pub replacement_name: UnresolvedItemName,
3472}
3473
3474impl AstDisplay for AlterMaterializedViewApplyReplacementStatement {
3475 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3476 where
3477 W: fmt::Write,
3478 {
3479 f.write_str("ALTER MATERIALIZED VIEW ");
3480 if self.if_exists {
3481 f.write_str("IF EXISTS ");
3482 }
3483 f.write_node(&self.name);
3484
3485 f.write_str(" APPLY REPLACEMENT ");
3486 f.write_node(&self.replacement_name);
3487 }
3488}
3489
3490impl_display!(AlterMaterializedViewApplyReplacementStatement);
3491
3492#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3493pub struct DiscardStatement {
3494 pub target: DiscardTarget,
3495}
3496
3497impl AstDisplay for DiscardStatement {
3498 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3499 f.write_str("DISCARD ");
3500 f.write_node(&self.target);
3501 }
3502}
3503impl_display!(DiscardStatement);
3504
3505#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3506pub enum DiscardTarget {
3507 Plans,
3508 Sequences,
3509 Temp,
3510 All,
3511}
3512
3513impl AstDisplay for DiscardTarget {
3514 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3515 match self {
3516 DiscardTarget::Plans => f.write_str("PLANS"),
3517 DiscardTarget::Sequences => f.write_str("SEQUENCES"),
3518 DiscardTarget::Temp => f.write_str("TEMP"),
3519 DiscardTarget::All => f.write_str("ALL"),
3520 }
3521 }
3522}
3523impl_display!(DiscardTarget);
3524
3525#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3527pub struct DropObjectsStatement {
3528 pub object_type: ObjectType,
3530 pub if_exists: bool,
3532 pub names: Vec<UnresolvedObjectName>,
3534 pub cascade: bool,
3537}
3538
3539impl AstDisplay for DropObjectsStatement {
3540 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3541 f.write_str("DROP ");
3542 f.write_node(&self.object_type);
3543 f.write_str(" ");
3544 if self.if_exists {
3545 f.write_str("IF EXISTS ");
3546 }
3547 f.write_node(&display::comma_separated(&self.names));
3548 if self.cascade && self.object_type != ObjectType::Database {
3549 f.write_str(" CASCADE");
3550 } else if !self.cascade && self.object_type == ObjectType::Database {
3551 f.write_str(" RESTRICT");
3552 }
3553 }
3554}
3555impl_display!(DropObjectsStatement);
3556
3557#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3559pub struct DropOwnedStatement<T: AstInfo> {
3560 pub role_names: Vec<T::RoleName>,
3562 pub cascade: Option<bool>,
3565}
3566
3567impl<T: AstInfo> DropOwnedStatement<T> {
3568 pub fn cascade(&self) -> bool {
3569 self.cascade == Some(true)
3570 }
3571}
3572
3573impl<T: AstInfo> AstDisplay for DropOwnedStatement<T> {
3574 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3575 f.write_str("DROP OWNED BY ");
3576 f.write_node(&display::comma_separated(&self.role_names));
3577 if let Some(true) = self.cascade {
3578 f.write_str(" CASCADE");
3579 } else if let Some(false) = self.cascade {
3580 f.write_str(" RESTRICT");
3581 }
3582 }
3583}
3584impl_display_t!(DropOwnedStatement);
3585
3586#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3587pub struct QualifiedReplica {
3588 pub cluster: Ident,
3589 pub replica: Ident,
3590}
3591
3592impl AstDisplay for QualifiedReplica {
3593 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3594 f.write_node(&self.cluster);
3595 f.write_str(".");
3596 f.write_node(&self.replica);
3597 }
3598}
3599impl_display!(QualifiedReplica);
3600
3601#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3607pub struct SetVariableStatement {
3608 pub local: bool,
3609 pub variable: Ident,
3610 pub to: SetVariableTo,
3611}
3612
3613impl AstDisplay for SetVariableStatement {
3614 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3615 f.write_str("SET ");
3616 if self.local {
3617 f.write_str("LOCAL ");
3618 }
3619 f.write_node(&self.variable);
3620 f.write_str(" = ");
3621 f.write_node(&self.to);
3622 }
3623}
3624impl_display!(SetVariableStatement);
3625
3626#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3631pub struct ResetVariableStatement {
3632 pub variable: Ident,
3633}
3634
3635impl AstDisplay for ResetVariableStatement {
3636 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3637 f.write_str("RESET ");
3638 f.write_node(&self.variable);
3639 }
3640}
3641impl_display!(ResetVariableStatement);
3642
3643#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3645pub struct ShowVariableStatement {
3646 pub variable: Ident,
3647}
3648
3649impl AstDisplay for ShowVariableStatement {
3650 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3651 f.write_str("SHOW ");
3652 f.write_node(&self.variable);
3653 }
3654}
3655impl_display!(ShowVariableStatement);
3656
3657#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3659pub struct InspectShardStatement {
3660 pub id: String,
3661}
3662
3663impl AstDisplay for InspectShardStatement {
3664 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3665 f.write_str("INSPECT SHARD ");
3666 f.write_str("'");
3667 f.write_node(&display::escape_single_quote_string(&self.id));
3668 f.write_str("'");
3669 }
3670}
3671impl_display!(InspectShardStatement);
3672
3673#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3674pub enum ShowObjectType<T: AstInfo> {
3675 MaterializedView {
3676 in_cluster: Option<T::ClusterName>,
3677 },
3678 Index {
3679 in_cluster: Option<T::ClusterName>,
3680 on_object: Option<T::ItemName>,
3681 },
3682 Table {
3683 on_source: Option<T::ItemName>,
3684 },
3685 View,
3686 Source {
3687 in_cluster: Option<T::ClusterName>,
3688 },
3689 Sink {
3690 in_cluster: Option<T::ClusterName>,
3691 },
3692 MetricSink {
3693 in_cluster: Option<T::ClusterName>,
3694 },
3695 Type,
3696 Role,
3697 Cluster,
3698 ClusterReplica,
3699 Object,
3700 Secret,
3701 Connection,
3702 Database,
3703 Schema {
3704 from: Option<T::DatabaseName>,
3705 },
3706 Subsource {
3707 on_source: Option<T::ItemName>,
3708 },
3709 Privileges {
3710 object_type: Option<SystemObjectType>,
3711 role: Option<T::RoleName>,
3712 },
3713 DefaultPrivileges {
3714 object_type: Option<ObjectType>,
3715 role: Option<T::RoleName>,
3716 },
3717 RoleMembership {
3718 role: Option<T::RoleName>,
3719 },
3720 NetworkPolicy,
3721}
3722#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3731pub struct ShowObjectsStatement<T: AstInfo> {
3732 pub object_type: ShowObjectType<T>,
3733 pub from: Option<T::SchemaName>,
3734 pub filter: Option<ShowStatementFilter<T>>,
3735}
3736
3737impl<T: AstInfo> AstDisplay for ShowObjectsStatement<T> {
3738 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3739 f.write_str("SHOW");
3740 f.write_str(" ");
3741
3742 f.write_str(match &self.object_type {
3743 ShowObjectType::Table { .. } => "TABLES",
3744 ShowObjectType::View => "VIEWS",
3745 ShowObjectType::Source { .. } => "SOURCES",
3746 ShowObjectType::Sink { .. } => "SINKS",
3747 ShowObjectType::MetricSink { .. } => "METRIC SINKS",
3748 ShowObjectType::Type => "TYPES",
3749 ShowObjectType::Role => "ROLES",
3750 ShowObjectType::Cluster => "CLUSTERS",
3751 ShowObjectType::ClusterReplica => "CLUSTER REPLICAS",
3752 ShowObjectType::Object => "OBJECTS",
3753 ShowObjectType::Secret => "SECRETS",
3754 ShowObjectType::Connection => "CONNECTIONS",
3755 ShowObjectType::MaterializedView { .. } => "MATERIALIZED VIEWS",
3756 ShowObjectType::Index { .. } => "INDEXES",
3757 ShowObjectType::Database => "DATABASES",
3758 ShowObjectType::Schema { .. } => "SCHEMAS",
3759 ShowObjectType::Subsource { .. } => "SUBSOURCES",
3760 ShowObjectType::Privileges { .. } => "PRIVILEGES",
3761 ShowObjectType::DefaultPrivileges { .. } => "DEFAULT PRIVILEGES",
3762 ShowObjectType::RoleMembership { .. } => "ROLE MEMBERSHIP",
3763 ShowObjectType::NetworkPolicy => "NETWORK POLICIES",
3764 });
3765
3766 if let ShowObjectType::Index { on_object, .. } = &self.object_type {
3767 if let Some(on_object) = on_object {
3768 f.write_str(" ON ");
3769 f.write_node(on_object);
3770 }
3771 }
3772
3773 if let ShowObjectType::Schema { from: Some(from) } = &self.object_type {
3774 f.write_str(" FROM ");
3775 f.write_node(from);
3776 }
3777
3778 if let Some(from) = &self.from {
3779 f.write_str(" FROM ");
3780 f.write_node(from);
3781 }
3782
3783 match &self.object_type {
3785 ShowObjectType::MaterializedView { in_cluster }
3786 | ShowObjectType::Index { in_cluster, .. }
3787 | ShowObjectType::Sink { in_cluster }
3788 | ShowObjectType::MetricSink { in_cluster }
3789 | ShowObjectType::Source { in_cluster } => {
3790 if let Some(cluster) = in_cluster {
3791 f.write_str(" IN CLUSTER ");
3792 f.write_node(cluster);
3793 }
3794 }
3795 _ => (),
3796 }
3797
3798 if let ShowObjectType::Subsource { on_source } = &self.object_type {
3799 if let Some(on_source) = on_source {
3800 f.write_str(" ON ");
3801 f.write_node(on_source);
3802 }
3803 }
3804
3805 if let ShowObjectType::Table { on_source } = &self.object_type {
3806 if let Some(on_source) = on_source {
3807 f.write_str(" ON ");
3808 f.write_node(on_source);
3809 }
3810 }
3811
3812 if let ShowObjectType::Privileges { object_type, role } = &self.object_type {
3813 if let Some(object_type) = object_type {
3814 f.write_str(" ON ");
3815 f.write_node(object_type);
3816 if let SystemObjectType::Object(_) = object_type {
3817 f.write_str("S");
3818 }
3819 }
3820 if let Some(role) = role {
3821 f.write_str(" FOR ");
3822 f.write_node(role);
3823 }
3824 }
3825
3826 if let ShowObjectType::DefaultPrivileges { object_type, role } = &self.object_type {
3827 if let Some(object_type) = object_type {
3828 f.write_str(" ON ");
3829 f.write_node(object_type);
3830 f.write_str("S");
3831 }
3832 if let Some(role) = role {
3833 f.write_str(" FOR ");
3834 f.write_node(role);
3835 }
3836 }
3837
3838 if let ShowObjectType::RoleMembership {
3839 role: Some(role), ..
3840 } = &self.object_type
3841 {
3842 f.write_str(" FOR ");
3843 f.write_node(role);
3844 }
3845
3846 if let Some(filter) = &self.filter {
3847 f.write_str(" ");
3848 f.write_node(filter);
3849 }
3850 }
3851}
3852impl_display_t!(ShowObjectsStatement);
3853
3854#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3858pub struct ShowColumnsStatement<T: AstInfo> {
3859 pub table_name: T::ItemName,
3860 pub filter: Option<ShowStatementFilter<T>>,
3861}
3862
3863impl<T: AstInfo> AstDisplay for ShowColumnsStatement<T> {
3864 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3865 f.write_str("SHOW ");
3866 f.write_str("COLUMNS FROM ");
3867 f.write_node(&self.table_name);
3868 if let Some(filter) = &self.filter {
3869 f.write_str(" ");
3870 f.write_node(filter);
3871 }
3872 }
3873}
3874impl_display_t!(ShowColumnsStatement);
3875
3876#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3878pub struct ShowCreateViewStatement<T: AstInfo> {
3879 pub view_name: T::ItemName,
3880 pub redacted: bool,
3881}
3882
3883impl<T: AstInfo> AstDisplay for ShowCreateViewStatement<T> {
3884 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3885 f.write_str("SHOW ");
3886 if self.redacted {
3887 f.write_str("REDACTED ");
3888 }
3889 f.write_str("CREATE VIEW ");
3890 f.write_node(&self.view_name);
3891 }
3892}
3893impl_display_t!(ShowCreateViewStatement);
3894
3895#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3897pub struct ShowCreateMaterializedViewStatement<T: AstInfo> {
3898 pub materialized_view_name: T::ItemName,
3899 pub redacted: bool,
3900}
3901
3902impl<T: AstInfo> AstDisplay for ShowCreateMaterializedViewStatement<T> {
3903 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3904 f.write_str("SHOW ");
3905 if self.redacted {
3906 f.write_str("REDACTED ");
3907 }
3908 f.write_str("CREATE MATERIALIZED VIEW ");
3909 f.write_node(&self.materialized_view_name);
3910 }
3911}
3912impl_display_t!(ShowCreateMaterializedViewStatement);
3913
3914#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3916pub struct ShowCreateSourceStatement<T: AstInfo> {
3917 pub source_name: T::ItemName,
3918 pub redacted: bool,
3919}
3920
3921impl<T: AstInfo> AstDisplay for ShowCreateSourceStatement<T> {
3922 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3923 f.write_str("SHOW ");
3924 if self.redacted {
3925 f.write_str("REDACTED ");
3926 }
3927 f.write_str("CREATE SOURCE ");
3928 f.write_node(&self.source_name);
3929 }
3930}
3931impl_display_t!(ShowCreateSourceStatement);
3932
3933#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3935pub struct ShowCreateTableStatement<T: AstInfo> {
3936 pub table_name: T::ItemName,
3937 pub redacted: bool,
3938}
3939
3940impl<T: AstInfo> AstDisplay for ShowCreateTableStatement<T> {
3941 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3942 f.write_str("SHOW ");
3943 if self.redacted {
3944 f.write_str("REDACTED ");
3945 }
3946 f.write_str("CREATE TABLE ");
3947 f.write_node(&self.table_name);
3948 }
3949}
3950impl_display_t!(ShowCreateTableStatement);
3951
3952#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3954pub struct ShowCreateSinkStatement<T: AstInfo> {
3955 pub sink_name: T::ItemName,
3956 pub redacted: bool,
3957}
3958
3959impl<T: AstInfo> AstDisplay for ShowCreateSinkStatement<T> {
3960 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3961 f.write_str("SHOW ");
3962 if self.redacted {
3963 f.write_str("REDACTED ");
3964 }
3965 f.write_str("CREATE SINK ");
3966 f.write_node(&self.sink_name);
3967 }
3968}
3969impl_display_t!(ShowCreateSinkStatement);
3970
3971#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3973pub struct ShowCreateMetricSinkStatement<T: AstInfo> {
3974 pub metric_sink_name: T::ItemName,
3975 pub redacted: bool,
3976}
3977
3978impl<T: AstInfo> AstDisplay for ShowCreateMetricSinkStatement<T> {
3979 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3980 f.write_str("SHOW ");
3981 if self.redacted {
3982 f.write_str("REDACTED ");
3983 }
3984 f.write_str("CREATE METRIC SINK ");
3985 f.write_node(&self.metric_sink_name);
3986 }
3987}
3988impl_display_t!(ShowCreateMetricSinkStatement);
3989
3990#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3992pub struct ShowCreateIndexStatement<T: AstInfo> {
3993 pub index_name: T::ItemName,
3994 pub redacted: bool,
3995}
3996
3997impl<T: AstInfo> AstDisplay for ShowCreateIndexStatement<T> {
3998 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3999 f.write_str("SHOW ");
4000 if self.redacted {
4001 f.write_str("REDACTED ");
4002 }
4003 f.write_str("CREATE INDEX ");
4004 f.write_node(&self.index_name);
4005 }
4006}
4007impl_display_t!(ShowCreateIndexStatement);
4008
4009#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4011pub struct ShowCreateConnectionStatement<T: AstInfo> {
4012 pub connection_name: T::ItemName,
4013 pub redacted: bool,
4014}
4015
4016impl<T: AstInfo> AstDisplay for ShowCreateConnectionStatement<T> {
4017 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4018 f.write_str("SHOW ");
4019 if self.redacted {
4020 f.write_str("REDACTED ");
4021 }
4022 f.write_str("CREATE CONNECTION ");
4023 f.write_node(&self.connection_name);
4024 }
4025}
4026
4027#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4028pub struct ShowCreateClusterStatement<T: AstInfo> {
4029 pub cluster_name: T::ClusterName,
4030}
4031
4032impl<T: AstInfo> AstDisplay for ShowCreateClusterStatement<T> {
4033 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4034 f.write_str("SHOW CREATE CLUSTER ");
4035 f.write_node(&self.cluster_name);
4036 }
4037}
4038
4039#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4041pub struct StartTransactionStatement {
4042 pub modes: Vec<TransactionMode>,
4043}
4044
4045impl AstDisplay for StartTransactionStatement {
4046 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4047 f.write_str("START TRANSACTION");
4048 if !self.modes.is_empty() {
4049 f.write_str(" ");
4050 f.write_node(&display::comma_separated(&self.modes));
4051 }
4052 }
4053}
4054impl_display!(StartTransactionStatement);
4055
4056#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4058pub struct ShowCreateTypeStatement<T: AstInfo> {
4059 pub type_name: T::DataType,
4060 pub redacted: bool,
4061}
4062
4063impl<T: AstInfo> AstDisplay for ShowCreateTypeStatement<T> {
4064 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4065 f.write_str("SHOW ");
4066 if self.redacted {
4067 f.write_str("REDACTED ");
4068 }
4069 f.write_str("CREATE TYPE ");
4070 f.write_node(&self.type_name);
4071 }
4072}
4073
4074#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4076pub struct SetTransactionStatement {
4077 pub local: bool,
4078 pub modes: Vec<TransactionMode>,
4079}
4080
4081impl AstDisplay for SetTransactionStatement {
4082 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4083 f.write_str("SET ");
4084 if !self.local {
4085 f.write_str("SESSION CHARACTERISTICS AS ");
4086 }
4087 f.write_str("TRANSACTION");
4088 if !self.modes.is_empty() {
4089 f.write_str(" ");
4090 f.write_node(&display::comma_separated(&self.modes));
4091 }
4092 }
4093}
4094impl_display!(SetTransactionStatement);
4095
4096#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4098pub struct CommitStatement {
4099 pub chain: bool,
4100}
4101
4102impl AstDisplay for CommitStatement {
4103 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4104 f.write_str("COMMIT");
4105 if self.chain {
4106 f.write_str(" AND CHAIN");
4107 }
4108 }
4109}
4110impl_display!(CommitStatement);
4111
4112#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4114pub struct RollbackStatement {
4115 pub chain: bool,
4116}
4117
4118impl AstDisplay for RollbackStatement {
4119 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4120 f.write_str("ROLLBACK");
4121 if self.chain {
4122 f.write_str(" AND CHAIN");
4123 }
4124 }
4125}
4126impl_display!(RollbackStatement);
4127
4128#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4129pub enum SubscribeOptionName {
4130 Snapshot,
4131 Progress,
4132}
4133
4134impl AstDisplay for SubscribeOptionName {
4135 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4136 match self {
4137 SubscribeOptionName::Snapshot => f.write_str("SNAPSHOT"),
4138 SubscribeOptionName::Progress => f.write_str("PROGRESS"),
4139 }
4140 }
4141}
4142impl_display!(SubscribeOptionName);
4143
4144impl WithOptionName for SubscribeOptionName {
4145 fn redact_value(&self) -> bool {
4151 match self {
4152 SubscribeOptionName::Snapshot | SubscribeOptionName::Progress => false,
4153 }
4154 }
4155}
4156
4157#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4158pub struct SubscribeOption<T: AstInfo> {
4159 pub name: SubscribeOptionName,
4160 pub value: Option<WithOptionValue<T>>,
4161}
4162impl_display_for_with_option!(SubscribeOption);
4163impl_display_t!(SubscribeOption);
4164
4165#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4167pub struct SubscribeStatement<T: AstInfo> {
4168 pub relation: SubscribeRelation<T>,
4169 pub options: Vec<SubscribeOption<T>>,
4170 pub as_of: Option<AsOf<T>>,
4171 pub up_to: Option<Expr<T>>,
4172 pub output: SubscribeOutput<T>,
4173}
4174
4175impl<T: AstInfo> AstDisplay for SubscribeStatement<T> {
4176 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4177 f.write_str("SUBSCRIBE ");
4178 if self.relation.needs_explicit_to(f.simple()) {
4179 f.write_str("TO ");
4184 }
4185 f.write_node(&self.relation);
4186 if !self.options.is_empty() {
4187 f.write_str(" WITH (");
4188 f.write_node(&display::comma_separated(&self.options));
4189 f.write_str(")");
4190 }
4191 if let Some(as_of) = &self.as_of {
4192 f.write_str(" ");
4193 f.write_node(as_of);
4194 }
4195 if let Some(up_to) = &self.up_to {
4196 f.write_str(" UP TO ");
4197 f.write_node(up_to);
4198 }
4199 f.write_str(&self.output);
4200 }
4201}
4202impl_display_t!(SubscribeStatement);
4203
4204#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4205pub enum SubscribeRelation<T: AstInfo> {
4206 Name(T::ItemName),
4207 Query(Query<T>),
4208}
4209
4210impl<T: AstInfo> SubscribeRelation<T> {
4211 pub fn needs_explicit_to(&self, bare_identifiers: bool) -> bool {
4215 let SubscribeRelation::Name(name) = self else {
4216 return false;
4217 };
4218 bare_identifiers && name_starts_with_bare_to(&name.to_ast_string_simple())
4219 }
4220}
4221
4222fn name_starts_with_bare_to(name: &str) -> bool {
4223 let Some(rest) = name.strip_prefix("to") else {
4224 return false;
4225 };
4226 rest.is_empty() || rest.starts_with('.')
4227}
4228
4229impl<T: AstInfo> AstDisplay for SubscribeRelation<T> {
4230 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4231 match self {
4232 SubscribeRelation::Name(name) => f.write_node(name),
4233 SubscribeRelation::Query(query) => {
4234 f.write_str("(");
4235 f.write_node(query);
4236 f.write_str(")");
4237 }
4238 }
4239 }
4240}
4241impl_display_t!(SubscribeRelation);
4242
4243#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4244pub struct ExplainPlanStatement<T: AstInfo> {
4245 pub stage: Option<ExplainStage>,
4246 pub with_options: Vec<ExplainPlanOption<T>>,
4247 pub format: Option<ExplainFormat>,
4248 pub explainee: Explainee<T>,
4249}
4250
4251impl<T: AstInfo> ExplainPlanStatement<T> {
4252 pub fn stage(&self) -> ExplainStage {
4253 self.stage.unwrap_or(ExplainStage::PhysicalPlan)
4254 }
4255
4256 pub fn format(&self) -> ExplainFormat {
4257 self.format.unwrap_or(ExplainFormat::Text)
4258 }
4259}
4260
4261impl<T: AstInfo> AstDisplay for ExplainPlanStatement<T> {
4262 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4263 f.write_str("EXPLAIN");
4264 if let Some(stage) = &self.stage {
4265 f.write_str(" ");
4266 f.write_node(stage);
4267 }
4268 if !self.with_options.is_empty() {
4269 f.write_str(" WITH (");
4270 f.write_node(&display::comma_separated(&self.with_options));
4271 f.write_str(")");
4272 }
4273 if let Some(format) = &self.format {
4274 f.write_str(" AS ");
4275 f.write_node(format);
4276 }
4277 if self.stage.is_some() {
4278 f.write_str(" FOR");
4279 }
4280 f.write_str(" ");
4281 f.write_node(&self.explainee);
4282 }
4283}
4284impl_display_t!(ExplainPlanStatement);
4285
4286#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4289pub enum ExplainPlanOptionName {
4290 Arity,
4291 Cardinality,
4292 ColumnNames,
4293 FilterPushdown,
4294 HumanizedExpressions,
4295 JoinImplementations,
4296 Keys,
4297 LinearChains,
4298 NonNegative,
4299 NoFastPath,
4300 NoNotices,
4301 NodeIdentifiers,
4302 RawPlans,
4303 RawSyntax,
4304 Raw, Redacted,
4306 SubtreeSize,
4307 Timing,
4308 Types,
4309 Equivalences,
4310 ReoptimizeImportedViews,
4311 EnableNewOuterJoinLowering,
4312 EnableEagerDeltaJoins,
4313 EnableVariadicLeftJoinLowering,
4314 EnableLetrecFixpointAnalysis,
4315 EnableJoinPrioritizeArranged,
4316 EnableProjectionPushdownAfterRelationCse,
4317 EnableFixedCorrelatedCteLowering,
4318 EnableUnionCancellationAfterRelationCse,
4319}
4320
4321impl WithOptionName for ExplainPlanOptionName {
4322 fn redact_value(&self) -> bool {
4328 match self {
4329 Self::Arity
4330 | Self::Cardinality
4331 | Self::ColumnNames
4332 | Self::FilterPushdown
4333 | Self::HumanizedExpressions
4334 | Self::JoinImplementations
4335 | Self::Keys
4336 | Self::LinearChains
4337 | Self::NonNegative
4338 | Self::NoFastPath
4339 | Self::NoNotices
4340 | Self::NodeIdentifiers
4341 | Self::RawPlans
4342 | Self::RawSyntax
4343 | Self::Raw
4344 | Self::Redacted
4345 | Self::SubtreeSize
4346 | Self::Timing
4347 | Self::Types
4348 | Self::Equivalences
4349 | Self::ReoptimizeImportedViews
4350 | Self::EnableNewOuterJoinLowering
4351 | Self::EnableEagerDeltaJoins
4352 | Self::EnableVariadicLeftJoinLowering
4353 | Self::EnableLetrecFixpointAnalysis
4354 | Self::EnableJoinPrioritizeArranged
4355 | Self::EnableProjectionPushdownAfterRelationCse
4356 | Self::EnableFixedCorrelatedCteLowering
4357 | Self::EnableUnionCancellationAfterRelationCse => false,
4358 }
4359 }
4360}
4361
4362#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4363pub struct ExplainPlanOption<T: AstInfo> {
4364 pub name: ExplainPlanOptionName,
4365 pub value: Option<WithOptionValue<T>>,
4366}
4367impl_display_for_with_option!(ExplainPlanOption);
4368
4369#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4370pub enum ExplainSinkSchemaFor {
4371 Key,
4372 Value,
4373}
4374#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4375pub struct ExplainSinkSchemaStatement<T: AstInfo> {
4376 pub schema_for: ExplainSinkSchemaFor,
4377 pub format: Option<ExplainFormat>,
4378 pub statement: CreateSinkStatement<T>,
4379}
4380
4381impl<T: AstInfo> AstDisplay for ExplainSinkSchemaStatement<T> {
4382 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4383 f.write_str("EXPLAIN ");
4384 match &self.schema_for {
4385 ExplainSinkSchemaFor::Key => f.write_str("KEY"),
4386 ExplainSinkSchemaFor::Value => f.write_str("VALUE"),
4387 }
4388 f.write_str(" SCHEMA");
4389 if let Some(format) = &self.format {
4390 f.write_str(" AS ");
4391 f.write_node(format);
4392 }
4393 f.write_str(" FOR ");
4394 f.write_node(&self.statement);
4395 }
4396}
4397impl_display_t!(ExplainSinkSchemaStatement);
4398
4399#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4400pub struct ExplainPushdownStatement<T: AstInfo> {
4401 pub explainee: Explainee<T>,
4402}
4403
4404impl<T: AstInfo> AstDisplay for ExplainPushdownStatement<T> {
4405 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4406 f.write_str("EXPLAIN FILTER PUSHDOWN FOR ");
4407 f.write_node(&self.explainee);
4408 }
4409}
4410impl_display_t!(ExplainPushdownStatement);
4411
4412#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
4413pub enum ExplainAnalyzeComputationProperty {
4414 Cpu,
4415 Memory,
4416}
4417
4418#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4419pub enum ExplainAnalyzeProperty {
4420 Computation(ExplainAnalyzeComputationProperties),
4421 Hints,
4422}
4423
4424#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4425pub struct ExplainAnalyzeComputationProperties {
4426 pub properties: Vec<ExplainAnalyzeComputationProperty>,
4428 pub skew: bool,
4429}
4430#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4431pub struct ExplainAnalyzeObjectStatement<T: AstInfo> {
4432 pub properties: ExplainAnalyzeProperty,
4433 pub explainee: Explainee<T>,
4435 pub as_sql: bool,
4436}
4437
4438impl<T: AstInfo> AstDisplay for ExplainAnalyzeObjectStatement<T> {
4439 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4440 f.write_str("EXPLAIN ANALYZE");
4441 match &self.properties {
4442 ExplainAnalyzeProperty::Computation(ExplainAnalyzeComputationProperties {
4443 properties,
4444 skew,
4445 }) => {
4446 let mut first = true;
4447 for property in properties {
4448 if first {
4449 first = false;
4450 } else {
4451 f.write_str(",");
4452 }
4453 match property {
4454 ExplainAnalyzeComputationProperty::Cpu => f.write_str(" CPU"),
4455 ExplainAnalyzeComputationProperty::Memory => f.write_str(" MEMORY"),
4456 }
4457 }
4458 if *skew {
4459 f.write_str(" WITH SKEW");
4460 }
4461 }
4462 ExplainAnalyzeProperty::Hints => f.write_str(" HINTS"),
4463 }
4464 f.write_str(" FOR ");
4465 f.write_node(&self.explainee);
4466 if self.as_sql {
4467 f.write_str(" AS SQL");
4468 }
4469 }
4470}
4471impl_display_t!(ExplainAnalyzeObjectStatement);
4472
4473#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4474pub struct ExplainAnalyzeClusterStatement {
4475 pub properties: ExplainAnalyzeComputationProperties,
4476 pub as_sql: bool,
4477}
4478
4479impl AstDisplay for ExplainAnalyzeClusterStatement {
4480 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4481 f.write_str("EXPLAIN ANALYZE CLUSTER");
4482
4483 let mut first = true;
4484 for property in &self.properties.properties {
4485 if first {
4486 first = false;
4487 } else {
4488 f.write_str(",");
4489 }
4490 match property {
4491 ExplainAnalyzeComputationProperty::Cpu => f.write_str(" CPU"),
4492 ExplainAnalyzeComputationProperty::Memory => f.write_str(" MEMORY"),
4493 }
4494 }
4495
4496 if self.properties.skew {
4497 f.write_str(" WITH SKEW");
4498 }
4499 if self.as_sql {
4500 f.write_str(" AS SQL");
4501 }
4502 }
4503}
4504impl_display!(ExplainAnalyzeClusterStatement);
4505
4506#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4507pub struct ExplainTimestampStatement<T: AstInfo> {
4508 pub format: Option<ExplainFormat>,
4509 pub select: SelectStatement<T>,
4510}
4511
4512impl<T: AstInfo> ExplainTimestampStatement<T> {
4513 pub fn format(&self) -> ExplainFormat {
4514 self.format.unwrap_or(ExplainFormat::Text)
4515 }
4516}
4517
4518impl<T: AstInfo> AstDisplay for ExplainTimestampStatement<T> {
4519 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4520 f.write_str("EXPLAIN TIMESTAMP");
4521 if let Some(format) = &self.format {
4522 f.write_str(" AS ");
4523 f.write_node(format);
4524 }
4525 f.write_str(" FOR ");
4526 f.write_node(&self.select);
4527 }
4528}
4529impl_display_t!(ExplainTimestampStatement);
4530
4531#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4532pub enum InsertSource<T: AstInfo> {
4533 Query(Query<T>),
4534 DefaultValues,
4535}
4536
4537impl<T: AstInfo> AstDisplay for InsertSource<T> {
4538 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4539 match self {
4540 InsertSource::Query(query) => f.write_node(query),
4541 InsertSource::DefaultValues => f.write_str("DEFAULT VALUES"),
4542 }
4543 }
4544}
4545impl_display_t!(InsertSource);
4546
4547#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
4548pub enum ObjectType {
4549 Table,
4550 View,
4551 MaterializedView,
4552 Source,
4553 Sink,
4554 MetricSink,
4555 Index,
4556 Type,
4557 Role,
4558 Cluster,
4559 ClusterReplica,
4560 Secret,
4561 Connection,
4562 Database,
4563 Schema,
4564 Func,
4565 Subsource,
4566 NetworkPolicy,
4567}
4568
4569impl ObjectType {
4570 pub fn lives_in_schema(&self) -> bool {
4571 match self {
4572 ObjectType::Table
4573 | ObjectType::View
4574 | ObjectType::MaterializedView
4575 | ObjectType::Source
4576 | ObjectType::Sink
4577 | ObjectType::MetricSink
4578 | ObjectType::Index
4579 | ObjectType::Type
4580 | ObjectType::Secret
4581 | ObjectType::Connection
4582 | ObjectType::Func
4583 | ObjectType::Subsource => true,
4584 ObjectType::Database
4585 | ObjectType::Schema
4586 | ObjectType::Cluster
4587 | ObjectType::ClusterReplica
4588 | ObjectType::Role
4589 | ObjectType::NetworkPolicy => false,
4590 }
4591 }
4592}
4593
4594impl AstDisplay for ObjectType {
4595 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4596 f.write_str(match self {
4597 ObjectType::Table => "TABLE",
4598 ObjectType::View => "VIEW",
4599 ObjectType::MaterializedView => "MATERIALIZED VIEW",
4600 ObjectType::Source => "SOURCE",
4601 ObjectType::Sink => "SINK",
4602 ObjectType::MetricSink => "METRIC SINK",
4603 ObjectType::Index => "INDEX",
4604 ObjectType::Type => "TYPE",
4605 ObjectType::Role => "ROLE",
4606 ObjectType::Cluster => "CLUSTER",
4607 ObjectType::ClusterReplica => "CLUSTER REPLICA",
4608 ObjectType::Secret => "SECRET",
4609 ObjectType::Connection => "CONNECTION",
4610 ObjectType::Database => "DATABASE",
4611 ObjectType::Schema => "SCHEMA",
4612 ObjectType::Func => "FUNCTION",
4613 ObjectType::Subsource => "SUBSOURCE",
4614 ObjectType::NetworkPolicy => "NETWORK POLICY",
4615 })
4616 }
4617}
4618impl_display!(ObjectType);
4619
4620#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
4621pub enum SystemObjectType {
4622 System,
4623 Object(ObjectType),
4624}
4625
4626impl AstDisplay for SystemObjectType {
4627 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4628 match self {
4629 SystemObjectType::System => f.write_str("SYSTEM"),
4630 SystemObjectType::Object(object) => f.write_node(object),
4631 }
4632 }
4633}
4634impl_display!(SystemObjectType);
4635
4636#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4637pub enum ShowStatementFilter<T: AstInfo> {
4638 Like(String),
4639 Where(Expr<T>),
4640}
4641
4642impl<T: AstInfo> AstDisplay for ShowStatementFilter<T> {
4643 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4644 use ShowStatementFilter::*;
4645 match self {
4646 Like(pattern) => {
4647 f.write_str("LIKE '");
4648 f.write_node(&display::escape_single_quote_string(pattern));
4649 f.write_str("'");
4650 }
4651 Where(expr) => {
4652 f.write_str("WHERE ");
4653 f.write_node(expr);
4654 }
4655 }
4656 }
4657}
4658impl_display_t!(ShowStatementFilter);
4659
4660#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4661pub enum WithOptionValue<T: AstInfo> {
4662 Value(Value),
4663 DataType(T::DataType),
4664 Secret(T::ItemName),
4665 Item(T::ItemName),
4666 UnresolvedItemName(UnresolvedItemName),
4667 Ident(Ident),
4668 Sequence(Vec<WithOptionValue<T>>),
4669 Map(BTreeMap<String, WithOptionValue<T>>),
4670 Expr(Expr<T>),
4672 ClusterReplicas(Vec<ReplicaDefinition<T>>),
4673 ConnectionKafkaBroker(KafkaBroker<T>),
4674 ConnectionAwsPrivatelink(ConnectionDefaultAwsPrivatelink<T>),
4675 KafkaMatchingBrokerRule(KafkaMatchingBrokerRule<T>),
4676 RetainHistoryFor(Value),
4677 Refresh(RefreshOptionValue<T>),
4678 ClusterScheduleOptionValue(ClusterScheduleOptionValue),
4679 ClusterAutoScalingStrategyOptionValue(ClusterAutoScalingStrategyOptionValue),
4680 ClusterAlterStrategy(ClusterAlterOptionValue<T>),
4681 NetworkPolicyRules(Vec<NetworkPolicyRuleDefinition<T>>),
4682}
4683
4684impl<T: AstInfo> AstDisplay for WithOptionValue<T> {
4685 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4686 if f.redacted() {
4687 match self {
4690 WithOptionValue::Value(_)
4691 | WithOptionValue::Sequence(_)
4692 | WithOptionValue::Map(_)
4693 | WithOptionValue::RetainHistoryFor(_)
4694 | WithOptionValue::Refresh(_)
4695 | WithOptionValue::Expr(_) => {
4696 }
4698 WithOptionValue::ConnectionKafkaBroker(_) => {
4699 f.write_str("'<REDACTED>'");
4700 return;
4701 }
4702 WithOptionValue::Secret(_) => {}
4708 WithOptionValue::DataType(_)
4709 | WithOptionValue::Item(_)
4710 | WithOptionValue::UnresolvedItemName(_)
4711 | WithOptionValue::Ident(_)
4712 | WithOptionValue::ConnectionAwsPrivatelink(_)
4713 | WithOptionValue::KafkaMatchingBrokerRule(_)
4714 | WithOptionValue::ClusterReplicas(_)
4715 | WithOptionValue::ClusterScheduleOptionValue(_)
4716 | WithOptionValue::ClusterAutoScalingStrategyOptionValue(_)
4717 | WithOptionValue::ClusterAlterStrategy(_)
4718 | WithOptionValue::NetworkPolicyRules(_) => {
4719 }
4721 }
4722 }
4723 match self {
4724 WithOptionValue::Sequence(values) => {
4725 f.write_str("(");
4726 f.write_node(&display::comma_separated(values));
4727 f.write_str(")");
4728 }
4729 WithOptionValue::Map(values) => {
4730 f.write_str("MAP[");
4731 let len = values.len();
4732 for (i, (key, value)) in values.iter().enumerate() {
4733 f.write_str("'");
4734 f.write_node(&display::escape_single_quote_string(key));
4735 f.write_str("' => ");
4736 f.write_node(value);
4737 if i + 1 < len {
4738 f.write_str(", ");
4739 }
4740 }
4741 f.write_str("]");
4742 }
4743 WithOptionValue::Expr(e) => f.write_node(e),
4744 WithOptionValue::Value(value) => f.write_node(value),
4745 WithOptionValue::DataType(typ) => f.write_node(typ),
4746 WithOptionValue::Secret(name) => {
4747 f.write_str("SECRET ");
4748 f.write_node(name)
4749 }
4750 WithOptionValue::Item(obj) => f.write_node(obj),
4751 WithOptionValue::UnresolvedItemName(r) => f.write_node(r),
4752 WithOptionValue::Ident(r) => f.write_node(r),
4753 WithOptionValue::ClusterReplicas(replicas) => {
4754 f.write_str("(");
4755 f.write_node(&display::comma_separated(replicas));
4756 f.write_str(")");
4757 }
4758 WithOptionValue::NetworkPolicyRules(rules) => {
4759 f.write_str("(");
4760 f.write_node(&display::comma_separated(rules));
4761 f.write_str(")");
4762 }
4763 WithOptionValue::ConnectionAwsPrivatelink(aws_privatelink) => {
4764 f.write_node(aws_privatelink);
4765 }
4766 WithOptionValue::KafkaMatchingBrokerRule(rule) => {
4767 f.write_node(rule);
4768 }
4769 WithOptionValue::ConnectionKafkaBroker(broker) => {
4770 f.write_node(broker);
4771 }
4772 WithOptionValue::RetainHistoryFor(value) => {
4773 f.write_str("FOR ");
4774 f.write_node(value);
4775 }
4776 WithOptionValue::Refresh(opt) => f.write_node(opt),
4777 WithOptionValue::ClusterScheduleOptionValue(value) => f.write_node(value),
4778 WithOptionValue::ClusterAutoScalingStrategyOptionValue(value) => f.write_node(value),
4779 WithOptionValue::ClusterAlterStrategy(value) => f.write_node(value),
4780 }
4781 }
4782}
4783impl_display_t!(WithOptionValue);
4784
4785#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4786pub enum RefreshOptionValue<T: AstInfo> {
4787 OnCommit,
4788 AtCreation,
4789 At(RefreshAtOptionValue<T>),
4790 Every(RefreshEveryOptionValue<T>),
4791}
4792
4793#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4794pub struct RefreshAtOptionValue<T: AstInfo> {
4795 pub time: Expr<T>,
4797}
4798
4799#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4800pub struct RefreshEveryOptionValue<T: AstInfo> {
4801 pub interval: IntervalValue,
4803 pub aligned_to: Option<Expr<T>>,
4805}
4806
4807impl<T: AstInfo> AstDisplay for RefreshOptionValue<T> {
4808 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4809 match self {
4810 RefreshOptionValue::OnCommit => {
4811 f.write_str("ON COMMIT");
4812 }
4813 RefreshOptionValue::AtCreation => {
4814 f.write_str("AT CREATION");
4815 }
4816 RefreshOptionValue::At(RefreshAtOptionValue { time }) => {
4817 f.write_str("AT ");
4818 f.write_node(time);
4819 }
4820 RefreshOptionValue::Every(RefreshEveryOptionValue {
4821 interval,
4822 aligned_to,
4823 }) => {
4824 f.write_str("EVERY '");
4825 f.write_node(interval);
4826 if let Some(aligned_to) = aligned_to {
4827 f.write_str(" ALIGNED TO ");
4828 f.write_node(aligned_to)
4829 }
4830 }
4831 }
4832 }
4833}
4834
4835#[derive(
4836 Debug,
4837 Clone,
4838 PartialEq,
4839 Eq,
4840 Hash,
4841 PartialOrd,
4842 Ord,
4843 Deserialize,
4844 Serialize
4845)]
4846pub enum ClusterScheduleOptionValue {
4847 Manual,
4848 Refresh {
4849 hydration_time_estimate: Option<IntervalValue>,
4850 },
4851}
4852
4853impl Default for ClusterScheduleOptionValue {
4854 fn default() -> Self {
4855 ClusterScheduleOptionValue::Manual
4857 }
4858}
4859
4860impl AstDisplay for ClusterScheduleOptionValue {
4861 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4862 match self {
4863 ClusterScheduleOptionValue::Manual => {
4864 f.write_str("MANUAL");
4865 }
4866 ClusterScheduleOptionValue::Refresh {
4867 hydration_time_estimate,
4868 } => {
4869 f.write_str("ON REFRESH");
4870 if let Some(hydration_time_estimate) = hydration_time_estimate {
4871 f.write_str(" (HYDRATION TIME ESTIMATE = '");
4872 f.write_node(hydration_time_estimate);
4873 f.write_str(")");
4874 }
4875 }
4876 }
4877 }
4878}
4879
4880#[derive(
4886 Debug,
4887 Clone,
4888 PartialEq,
4889 Eq,
4890 Hash,
4891 PartialOrd,
4892 Ord,
4893 Deserialize,
4894 Serialize
4895)]
4896pub struct ClusterAutoScalingStrategyOptionValue {
4897 pub on_hydration: Option<OnHydrationOptionValue>,
4898}
4899
4900impl AstDisplay for ClusterAutoScalingStrategyOptionValue {
4901 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4902 f.write_str("(");
4903 if let Some(on_hydration) = &self.on_hydration {
4904 f.write_node(on_hydration);
4905 }
4906 f.write_str(")");
4907 }
4908}
4909
4910#[derive(
4914 Debug,
4915 Clone,
4916 PartialEq,
4917 Eq,
4918 Hash,
4919 PartialOrd,
4920 Ord,
4921 Deserialize,
4922 Serialize
4923)]
4924pub struct OnHydrationOptionValue {
4925 pub hydration_size: Value,
4926 pub linger_duration: Option<Value>,
4927}
4928
4929impl AstDisplay for OnHydrationOptionValue {
4930 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4931 f.write_str("ON HYDRATION (HYDRATION SIZE = ");
4932 f.write_node(&self.hydration_size);
4933 if let Some(linger_duration) = &self.linger_duration {
4934 f.write_str(", LINGER DURATION = ");
4935 f.write_node(linger_duration);
4936 }
4937 f.write_str(")");
4938 }
4939}
4940
4941#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4942pub enum TransactionMode {
4943 AccessMode(TransactionAccessMode),
4944 IsolationLevel(TransactionIsolationLevel),
4945}
4946
4947impl AstDisplay for TransactionMode {
4948 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4949 use TransactionMode::*;
4950 match self {
4951 AccessMode(access_mode) => f.write_node(access_mode),
4952 IsolationLevel(iso_level) => {
4953 f.write_str("ISOLATION LEVEL ");
4954 f.write_node(iso_level);
4955 }
4956 }
4957 }
4958}
4959impl_display!(TransactionMode);
4960
4961#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4963pub enum TransactionAccessMode {
4964 ReadOnly,
4965 ReadWrite,
4966}
4967
4968impl AstDisplay for TransactionAccessMode {
4969 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4970 use TransactionAccessMode::*;
4971 f.write_str(match self {
4972 ReadOnly => "READ ONLY",
4973 ReadWrite => "READ WRITE",
4974 })
4975 }
4976}
4977impl_display!(TransactionAccessMode);
4978
4979#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
4980pub enum TransactionIsolationLevel {
4981 ReadUncommitted,
4982 ReadCommitted,
4983 RepeatableRead,
4984 Serializable,
4985 StrongSessionSerializable,
4986 StrictSerializable,
4987}
4988
4989impl AstDisplay for TransactionIsolationLevel {
4990 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4991 use TransactionIsolationLevel::*;
4992 f.write_str(match self {
4993 ReadUncommitted => "READ UNCOMMITTED",
4994 ReadCommitted => "READ COMMITTED",
4995 RepeatableRead => "REPEATABLE READ",
4996 Serializable => "SERIALIZABLE",
4997 StrongSessionSerializable => "STRONG SESSION SERIALIZABLE",
4998 StrictSerializable => "STRICT SERIALIZABLE",
4999 })
5000 }
5001}
5002impl_display!(TransactionIsolationLevel);
5003
5004#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5005pub enum SetVariableTo {
5006 Default,
5007 Values(Vec<SetVariableValue>),
5008}
5009
5010impl AstDisplay for SetVariableTo {
5011 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5012 use SetVariableTo::*;
5013 match self {
5014 Values(values) => f.write_node(&display::comma_separated(values)),
5015 Default => f.write_str("DEFAULT"),
5016 }
5017 }
5018}
5019impl_display!(SetVariableTo);
5020
5021#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5022pub enum SetVariableValue {
5023 Ident(Ident),
5024 Literal(Value),
5025}
5026
5027impl AstDisplay for SetVariableValue {
5028 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5029 use SetVariableValue::*;
5030 match self {
5031 Ident(ident) => f.write_node(ident),
5032 Literal(literal) => f.write_node(literal),
5033 }
5034 }
5035}
5036impl_display!(SetVariableValue);
5037
5038impl SetVariableValue {
5039 pub fn into_unquoted_value(self) -> String {
5041 match self {
5042 SetVariableValue::Literal(Value::String(s)) => s,
5045 SetVariableValue::Literal(lit) => lit.to_string(),
5046 SetVariableValue::Ident(ident) => ident.into_string(),
5047 }
5048 }
5049}
5050
5051#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5053pub struct Assignment<T: AstInfo> {
5054 pub id: Ident,
5055 pub value: Expr<T>,
5056}
5057
5058impl<T: AstInfo> AstDisplay for Assignment<T> {
5059 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5060 f.write_node(&self.id);
5061 f.write_str(" = ");
5062 f.write_node(&self.value);
5063 }
5064}
5065impl_display_t!(Assignment);
5066
5067#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5069pub enum ExplainStage {
5070 RawPlan,
5072 DecorrelatedPlan,
5074 LocalPlan,
5076 GlobalPlan,
5078 PhysicalPlan,
5080 Trace,
5082 PlanInsights,
5084}
5085
5086impl ExplainStage {
5087 pub fn paths(&self) -> Option<SmallVec<[NamedPlan; 4]>> {
5089 use NamedPlan::*;
5090 match self {
5091 Self::RawPlan => Some(smallvec![Raw]),
5092 Self::DecorrelatedPlan => Some(smallvec![Decorrelated]),
5093 Self::LocalPlan => Some(smallvec![Local]),
5094 Self::GlobalPlan => Some(smallvec![Global]),
5095 Self::PhysicalPlan => Some(smallvec![Physical]),
5096 Self::Trace => None,
5097 Self::PlanInsights => Some(smallvec![Raw, Global, FastPath]),
5098 }
5099 }
5100
5101 pub fn show_fast_path(&self) -> bool {
5104 match self {
5105 Self::RawPlan => false,
5106 Self::DecorrelatedPlan => false,
5107 Self::LocalPlan => false,
5108 Self::GlobalPlan => true,
5109 Self::PhysicalPlan => true,
5110 Self::Trace => false,
5111 Self::PlanInsights => false,
5112 }
5113 }
5114}
5115
5116impl AstDisplay for ExplainStage {
5117 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5118 match self {
5119 Self::RawPlan => f.write_str("RAW PLAN"),
5120 Self::DecorrelatedPlan => f.write_str("DECORRELATED PLAN"),
5121 Self::LocalPlan => f.write_str("LOCALLY OPTIMIZED PLAN"),
5122 Self::GlobalPlan => f.write_str("OPTIMIZED PLAN"),
5123 Self::PhysicalPlan => f.write_str("PHYSICAL PLAN"),
5124 Self::Trace => f.write_str("OPTIMIZER TRACE"),
5125 Self::PlanInsights => f.write_str("PLAN INSIGHTS"),
5126 }
5127 }
5128}
5129impl_display!(ExplainStage);
5130
5131#[derive(Clone)]
5134pub enum NamedPlan {
5135 Raw,
5136 Decorrelated,
5137 Local,
5138 Global,
5139 Physical,
5140 FastPath,
5141}
5142
5143impl NamedPlan {
5144 pub fn of_path(value: &str) -> Option<Self> {
5146 match value {
5147 "optimize/raw" => Some(Self::Raw),
5148 "optimize/hir_to_mir" => Some(Self::Decorrelated),
5149 "optimize/local" => Some(Self::Local),
5150 "optimize/global" => Some(Self::Global),
5151 "optimize/finalize_dataflow" => Some(Self::Physical),
5152 "optimize/fast_path" => Some(Self::FastPath),
5153 _ => None,
5154 }
5155 }
5156
5157 pub fn path(&self) -> &'static str {
5160 match self {
5161 Self::Raw => "optimize/raw",
5162 Self::Decorrelated => "optimize/hir_to_mir",
5163 Self::Local => "optimize/local",
5164 Self::Global => "optimize/global",
5165 Self::Physical => "optimize/finalize_dataflow",
5166 Self::FastPath => "optimize/fast_path",
5167 }
5168 }
5169}
5170
5171#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5174pub enum Explainee<T: AstInfo> {
5175 View(T::ItemName),
5176 MaterializedView(T::ItemName),
5177 Index(T::ItemName),
5178 ReplanView(T::ItemName),
5179 ReplanMaterializedView(T::ItemName),
5180 ReplanIndex(T::ItemName),
5181 Select(Box<SelectStatement<T>>, bool),
5182 CreateView(Box<CreateViewStatement<T>>, bool),
5183 CreateMaterializedView(Box<CreateMaterializedViewStatement<T>>, bool),
5184 CreateIndex(Box<CreateIndexStatement<T>>, bool),
5185 Subscribe(Box<SubscribeStatement<T>>, bool),
5186}
5187
5188impl<T: AstInfo> Explainee<T> {
5189 pub fn name(&self) -> Option<&T::ItemName> {
5190 match self {
5191 Self::View(name)
5192 | Self::ReplanView(name)
5193 | Self::MaterializedView(name)
5194 | Self::ReplanMaterializedView(name)
5195 | Self::Index(name)
5196 | Self::ReplanIndex(name) => Some(name),
5197 Self::Select(..)
5198 | Self::CreateView(..)
5199 | Self::CreateMaterializedView(..)
5200 | Self::CreateIndex(..)
5201 | Self::Subscribe(..) => None,
5202 }
5203 }
5204
5205 pub fn is_view(&self) -> bool {
5206 use Explainee::*;
5207 matches!(self, View(_) | ReplanView(_) | CreateView(_, _))
5208 }
5209}
5210
5211impl<T: AstInfo> AstDisplay for Explainee<T> {
5212 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5213 match self {
5214 Self::View(name) => {
5215 f.write_str("VIEW ");
5216 f.write_node(name);
5217 }
5218 Self::MaterializedView(name) => {
5219 f.write_str("MATERIALIZED VIEW ");
5220 f.write_node(name);
5221 }
5222 Self::Index(name) => {
5223 f.write_str("INDEX ");
5224 f.write_node(name);
5225 }
5226 Self::ReplanView(name) => {
5227 f.write_str("REPLAN VIEW ");
5228 f.write_node(name);
5229 }
5230 Self::ReplanMaterializedView(name) => {
5231 f.write_str("REPLAN MATERIALIZED VIEW ");
5232 f.write_node(name);
5233 }
5234 Self::ReplanIndex(name) => {
5235 f.write_str("REPLAN INDEX ");
5236 f.write_node(name);
5237 }
5238 Self::Select(select, broken) => {
5239 if *broken {
5240 f.write_str("BROKEN ");
5241 }
5242 f.write_node(select);
5243 }
5244 Self::CreateView(statement, broken) => {
5245 if *broken {
5246 f.write_str("BROKEN ");
5247 }
5248 f.write_node(statement);
5249 }
5250 Self::CreateMaterializedView(statement, broken) => {
5251 if *broken {
5252 f.write_str("BROKEN ");
5253 }
5254 f.write_node(statement);
5255 }
5256 Self::CreateIndex(statement, broken) => {
5257 if *broken {
5258 f.write_str("BROKEN ");
5259 }
5260 f.write_node(statement);
5261 }
5262 Self::Subscribe(statement, broken) => {
5263 if *broken {
5264 f.write_str("BROKEN ");
5265 }
5266 f.write_node(statement);
5267 }
5268 }
5269 }
5270}
5271impl_display_t!(Explainee);
5272
5273#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
5274pub enum ExplainFormat {
5275 Text,
5277 VerboseText,
5279 Json,
5281 Dot,
5283}
5284
5285impl AstDisplay for ExplainFormat {
5286 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5287 match self {
5288 Self::Text => f.write_str("TEXT"),
5289 Self::VerboseText => f.write_str("VERBOSE TEXT"),
5290 Self::Json => f.write_str("JSON"),
5291 Self::Dot => f.write_str("DOT"),
5292 }
5293 }
5294}
5295impl_display!(ExplainFormat);
5296
5297#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5298pub enum IfExistsBehavior {
5299 Error,
5300 Skip,
5301 Replace,
5302}
5303
5304#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5306pub struct DeclareStatement<T: AstInfo> {
5307 pub name: Ident,
5308 pub stmt: Box<T::NestedStatement>,
5309 pub sql: String,
5310}
5311
5312impl<T: AstInfo> AstDisplay for DeclareStatement<T> {
5313 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5314 f.write_str("DECLARE ");
5315 f.write_node(&self.name);
5316 f.write_str(" CURSOR FOR ");
5317 f.write_node(&self.stmt);
5318 }
5319}
5320impl_display_t!(DeclareStatement);
5321
5322#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5324pub struct CloseStatement {
5325 pub name: Ident,
5326}
5327
5328impl AstDisplay for CloseStatement {
5329 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5330 f.write_str("CLOSE ");
5331 f.write_node(&self.name);
5332 }
5333}
5334impl_display!(CloseStatement);
5335
5336#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5337pub enum FetchOptionName {
5338 Timeout,
5339}
5340
5341impl AstDisplay for FetchOptionName {
5342 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5343 f.write_str(match self {
5344 FetchOptionName::Timeout => "TIMEOUT",
5345 })
5346 }
5347}
5348
5349impl WithOptionName for FetchOptionName {
5350 fn redact_value(&self) -> bool {
5356 match self {
5357 FetchOptionName::Timeout => false,
5358 }
5359 }
5360}
5361
5362#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5363pub struct FetchOption<T: AstInfo> {
5364 pub name: FetchOptionName,
5365 pub value: Option<WithOptionValue<T>>,
5366}
5367impl_display_for_with_option!(FetchOption);
5368
5369#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5371pub struct FetchStatement<T: AstInfo> {
5372 pub name: Ident,
5373 pub count: Option<FetchDirection>,
5374 pub options: Vec<FetchOption<T>>,
5375}
5376
5377impl<T: AstInfo> AstDisplay for FetchStatement<T> {
5378 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5379 f.write_str("FETCH ");
5380 if let Some(ref count) = self.count {
5381 f.write_str(format!("{} ", count));
5382 }
5383 if self.count.is_none() && self.name.as_str().eq_ignore_ascii_case("forward") {
5387 f.write_str(self.name.to_ast_string_stable());
5388 } else {
5389 f.write_node(&self.name);
5390 }
5391 if !self.options.is_empty() {
5392 f.write_str(" WITH (");
5393 f.write_node(&display::comma_separated(&self.options));
5394 f.write_str(")");
5395 }
5396 }
5397}
5398impl_display_t!(FetchStatement);
5399
5400#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5401pub enum FetchDirection {
5402 ForwardAll,
5403 ForwardCount(u64),
5404}
5405
5406impl AstDisplay for FetchDirection {
5407 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5408 match self {
5409 FetchDirection::ForwardAll => f.write_str("ALL"),
5410 FetchDirection::ForwardCount(count) => f.write_str(format!("{}", count)),
5411 }
5412 }
5413}
5414impl_display!(FetchDirection);
5415
5416#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5418pub struct PrepareStatement<T: AstInfo> {
5419 pub name: Ident,
5420 pub stmt: Box<T::NestedStatement>,
5421 pub sql: String,
5422}
5423
5424impl<T: AstInfo> AstDisplay for PrepareStatement<T> {
5425 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5426 f.write_str("PREPARE ");
5427 f.write_node(&self.name);
5428 f.write_str(" AS ");
5429 f.write_node(&self.stmt);
5430 }
5431}
5432impl_display_t!(PrepareStatement);
5433
5434#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5436pub struct ExecuteStatement<T: AstInfo> {
5437 pub name: Ident,
5438 pub params: Vec<Expr<T>>,
5439}
5440
5441impl<T: AstInfo> AstDisplay for ExecuteStatement<T> {
5442 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5443 f.write_str("EXECUTE ");
5444 f.write_node(&self.name);
5445 if !self.params.is_empty() {
5446 f.write_str(" (");
5447 f.write_node(&display::comma_separated(&self.params));
5448 f.write_str(")");
5449 }
5450 }
5451}
5452impl_display_t!(ExecuteStatement);
5453
5454#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5456pub struct ExecuteUnitTestStatement<T: AstInfo> {
5457 pub name: Ident,
5458 pub target: T::ItemName,
5459 pub at_time: Option<Expr<T>>,
5460 pub mocks: Vec<MockViewDef<T>>,
5461 pub expected: ExpectedResultDef<T>,
5462}
5463
5464impl<T: AstInfo> AstDisplay for ExecuteUnitTestStatement<T> {
5465 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5466 f.write_str("EXECUTE UNIT TEST ");
5467 f.write_node(&self.name);
5468 f.write_str(" FOR ");
5469 f.write_node(&self.target);
5470 if let Some(at_time) = &self.at_time {
5471 f.write_str(" AT TIME ");
5472 f.write_node(at_time);
5473 }
5474 for (i, mock) in self.mocks.iter().enumerate() {
5475 f.write_str(if i == 0 { " MOCK " } else { ", MOCK " });
5476 f.write_node(mock);
5477 }
5478 f.write_str(" EXPECTED ");
5479 f.write_node(&self.expected);
5480 }
5481}
5482impl_display_t!(ExecuteUnitTestStatement);
5483
5484#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5486pub struct MockViewDef<T: AstInfo> {
5487 pub name: T::ItemName,
5488 pub columns: Vec<ColumnDef<T>>,
5489 pub query: Query<T>,
5490}
5491
5492impl<T: AstInfo> AstDisplay for MockViewDef<T> {
5493 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5494 f.write_node(&self.name);
5495 f.write_str("(");
5496 f.write_node(&display::comma_separated(&self.columns));
5497 f.write_str(") AS (");
5498 f.write_node(&self.query);
5499 f.write_str(")");
5500 }
5501}
5502impl_display_t!(MockViewDef);
5503
5504#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5506pub struct ExpectedResultDef<T: AstInfo> {
5507 pub columns: Vec<ColumnDef<T>>,
5508 pub query: Query<T>,
5509}
5510
5511impl<T: AstInfo> AstDisplay for ExpectedResultDef<T> {
5512 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5513 f.write_str("(");
5514 f.write_node(&display::comma_separated(&self.columns));
5515 f.write_str(") AS (");
5516 f.write_node(&self.query);
5517 f.write_str(")");
5518 }
5519}
5520impl_display_t!(ExpectedResultDef);
5521
5522#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5524pub struct DeallocateStatement {
5525 pub name: Option<Ident>,
5526}
5527
5528impl AstDisplay for DeallocateStatement {
5529 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5530 f.write_str("DEALLOCATE ");
5531 match &self.name {
5532 Some(name) => f.write_node(name),
5533 None => f.write_str("ALL"),
5534 };
5535 }
5536}
5537impl_display!(DeallocateStatement);
5538
5539#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5541pub struct RaiseStatement {
5542 pub severity: NoticeSeverity,
5543}
5544
5545impl AstDisplay for RaiseStatement {
5546 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5547 f.write_str("RAISE ");
5548 f.write_node(&self.severity);
5549 }
5550}
5551impl_display!(RaiseStatement);
5552
5553#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5554pub enum NoticeSeverity {
5555 Debug,
5556 Info,
5557 Log,
5558 Notice,
5559 Warning,
5560}
5561
5562impl AstDisplay for NoticeSeverity {
5563 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5564 f.write_str(match self {
5565 NoticeSeverity::Debug => "DEBUG",
5566 NoticeSeverity::Info => "INFO",
5567 NoticeSeverity::Log => "LOG",
5568 NoticeSeverity::Notice => "NOTICE",
5569 NoticeSeverity::Warning => "WARNING",
5570 })
5571 }
5572}
5573impl_display!(NoticeSeverity);
5574
5575#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5577pub struct AlterSystemSetStatement {
5578 pub name: Ident,
5579 pub to: SetVariableTo,
5580}
5581
5582impl AstDisplay for AlterSystemSetStatement {
5583 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5584 f.write_str("ALTER SYSTEM SET ");
5585 f.write_node(&self.name);
5586 f.write_str(" = ");
5587 f.write_node(&self.to);
5588 }
5589}
5590impl_display!(AlterSystemSetStatement);
5591
5592#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5594pub struct AlterSystemResetStatement {
5595 pub name: Ident,
5596}
5597
5598impl AstDisplay for AlterSystemResetStatement {
5599 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5600 f.write_str("ALTER SYSTEM RESET ");
5601 f.write_node(&self.name);
5602 }
5603}
5604impl_display!(AlterSystemResetStatement);
5605
5606#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5608pub struct AlterSystemResetAllStatement {}
5609
5610impl AstDisplay for AlterSystemResetAllStatement {
5611 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5612 f.write_str("ALTER SYSTEM RESET ALL");
5613 }
5614}
5615impl_display!(AlterSystemResetAllStatement);
5616
5617#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5618pub enum AsOf<T: AstInfo> {
5619 At(Expr<T>),
5620 AtLeast(Expr<T>),
5621}
5622
5623impl<T: AstInfo> AstDisplay for AsOf<T> {
5624 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5625 f.write_str("AS OF ");
5626 match self {
5627 AsOf::At(expr) => f.write_node(expr),
5628 AsOf::AtLeast(expr) => {
5629 f.write_str("AT LEAST ");
5630 f.write_node(expr);
5631 }
5632 }
5633 }
5634}
5635impl_display_t!(AsOf);
5636
5637#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
5638pub enum ShowStatement<T: AstInfo> {
5639 ShowObjects(ShowObjectsStatement<T>),
5640 ShowColumns(ShowColumnsStatement<T>),
5641 ShowCreateView(ShowCreateViewStatement<T>),
5642 ShowCreateMaterializedView(ShowCreateMaterializedViewStatement<T>),
5643 ShowCreateSource(ShowCreateSourceStatement<T>),
5644 ShowCreateTable(ShowCreateTableStatement<T>),
5645 ShowCreateSink(ShowCreateSinkStatement<T>),
5646 ShowCreateMetricSink(ShowCreateMetricSinkStatement<T>),
5647 ShowCreateIndex(ShowCreateIndexStatement<T>),
5648 ShowCreateConnection(ShowCreateConnectionStatement<T>),
5649 ShowCreateCluster(ShowCreateClusterStatement<T>),
5650 ShowCreateType(ShowCreateTypeStatement<T>),
5651 ShowVariable(ShowVariableStatement),
5652 InspectShard(InspectShardStatement),
5653}
5654
5655impl<T: AstInfo> AstDisplay for ShowStatement<T> {
5656 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5657 match self {
5658 ShowStatement::ShowObjects(stmt) => f.write_node(stmt),
5659 ShowStatement::ShowColumns(stmt) => f.write_node(stmt),
5660 ShowStatement::ShowCreateView(stmt) => f.write_node(stmt),
5661 ShowStatement::ShowCreateMaterializedView(stmt) => f.write_node(stmt),
5662 ShowStatement::ShowCreateSource(stmt) => f.write_node(stmt),
5663 ShowStatement::ShowCreateTable(stmt) => f.write_node(stmt),
5664 ShowStatement::ShowCreateSink(stmt) => f.write_node(stmt),
5665 ShowStatement::ShowCreateMetricSink(stmt) => f.write_node(stmt),
5666 ShowStatement::ShowCreateIndex(stmt) => f.write_node(stmt),
5667 ShowStatement::ShowCreateConnection(stmt) => f.write_node(stmt),
5668 ShowStatement::ShowCreateCluster(stmt) => f.write_node(stmt),
5669 ShowStatement::ShowCreateType(stmt) => f.write_node(stmt),
5670 ShowStatement::ShowVariable(stmt) => f.write_node(stmt),
5671 ShowStatement::InspectShard(stmt) => f.write_node(stmt),
5672 }
5673 }
5674}
5675impl_display_t!(ShowStatement);
5676
5677#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5679pub struct GrantRoleStatement<T: AstInfo> {
5680 pub role_names: Vec<T::RoleName>,
5682 pub member_names: Vec<T::RoleName>,
5684}
5685
5686impl<T: AstInfo> AstDisplay for GrantRoleStatement<T> {
5687 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5688 f.write_str("GRANT ");
5689 f.write_node(&display::comma_separated(&self.role_names));
5690 f.write_str(" TO ");
5691 f.write_node(&display::comma_separated(&self.member_names));
5692 }
5693}
5694impl_display_t!(GrantRoleStatement);
5695
5696#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5698pub struct RevokeRoleStatement<T: AstInfo> {
5699 pub role_names: Vec<T::RoleName>,
5701 pub member_names: Vec<T::RoleName>,
5703}
5704
5705impl<T: AstInfo> AstDisplay for RevokeRoleStatement<T> {
5706 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5707 f.write_str("REVOKE ");
5708 f.write_node(&display::comma_separated(&self.role_names));
5709 f.write_str(" FROM ");
5710 f.write_node(&display::comma_separated(&self.member_names));
5711 }
5712}
5713impl_display_t!(RevokeRoleStatement);
5714
5715#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5716pub enum Privilege {
5717 SELECT,
5718 INSERT,
5719 UPDATE,
5720 DELETE,
5721 USAGE,
5722 CREATE,
5723 CREATEROLE,
5724 CREATEDB,
5725 CREATECLUSTER,
5726 CREATENETWORKPOLICY,
5727}
5728
5729impl AstDisplay for Privilege {
5730 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5731 f.write_str(match self {
5732 Privilege::SELECT => "SELECT",
5733 Privilege::INSERT => "INSERT",
5734 Privilege::UPDATE => "UPDATE",
5735 Privilege::DELETE => "DELETE",
5736 Privilege::CREATE => "CREATE",
5737 Privilege::USAGE => "USAGE",
5738 Privilege::CREATEROLE => "CREATEROLE",
5739 Privilege::CREATEDB => "CREATEDB",
5740 Privilege::CREATECLUSTER => "CREATECLUSTER",
5741 Privilege::CREATENETWORKPOLICY => "CREATENETWORKPOLICY",
5742 });
5743 }
5744}
5745impl_display!(Privilege);
5746
5747#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5748pub enum PrivilegeSpecification {
5749 All,
5750 Privileges(Vec<Privilege>),
5751}
5752
5753impl AstDisplay for PrivilegeSpecification {
5754 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5755 match self {
5756 PrivilegeSpecification::All => f.write_str("ALL"),
5757 PrivilegeSpecification::Privileges(privileges) => {
5758 f.write_node(&display::comma_separated(privileges))
5759 }
5760 }
5761 }
5762}
5763impl_display!(PrivilegeSpecification);
5764
5765#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5766pub enum GrantTargetSpecification<T: AstInfo> {
5767 Object {
5768 object_type: ObjectType,
5772 object_spec_inner: GrantTargetSpecificationInner<T>,
5774 },
5775 System,
5776}
5777
5778#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5779pub enum GrantTargetSpecificationInner<T: AstInfo> {
5780 All(GrantTargetAllSpecification<T>),
5781 Objects { names: Vec<T::ObjectName> },
5782}
5783
5784#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5785pub enum GrantTargetAllSpecification<T: AstInfo> {
5786 All,
5787 AllDatabases { databases: Vec<T::DatabaseName> },
5788 AllSchemas { schemas: Vec<T::SchemaName> },
5789}
5790
5791impl<T: AstInfo> GrantTargetAllSpecification<T> {
5792 pub fn len(&self) -> usize {
5793 match self {
5794 GrantTargetAllSpecification::All => 1,
5795 GrantTargetAllSpecification::AllDatabases { databases } => databases.len(),
5796 GrantTargetAllSpecification::AllSchemas { schemas } => schemas.len(),
5797 }
5798 }
5799}
5800
5801fn write_grant_object_type_plural<W: fmt::Write>(
5807 f: &mut AstFormatter<W>,
5808 object_type: &ObjectType,
5809) {
5810 match object_type {
5811 ObjectType::NetworkPolicy => f.write_str("POLICIES"),
5812 other => {
5813 f.write_node(other);
5814 f.write_str("S");
5815 }
5816 }
5817}
5818
5819impl<T: AstInfo> AstDisplay for GrantTargetSpecification<T> {
5820 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5821 match self {
5822 GrantTargetSpecification::Object {
5823 object_type,
5824 object_spec_inner,
5825 } => match object_spec_inner {
5826 GrantTargetSpecificationInner::All(all_spec) => match all_spec {
5827 GrantTargetAllSpecification::All => {
5828 f.write_str("ALL ");
5829 write_grant_object_type_plural(f, object_type);
5830 }
5831 GrantTargetAllSpecification::AllDatabases { databases } => {
5832 f.write_str("ALL ");
5833 write_grant_object_type_plural(f, object_type);
5834 f.write_str(" IN DATABASE ");
5835 f.write_node(&display::comma_separated(databases));
5836 }
5837 GrantTargetAllSpecification::AllSchemas { schemas } => {
5838 f.write_str("ALL ");
5839 write_grant_object_type_plural(f, object_type);
5840 f.write_str(" IN SCHEMA ");
5841 f.write_node(&display::comma_separated(schemas));
5842 }
5843 },
5844 GrantTargetSpecificationInner::Objects { names } => {
5845 f.write_node(object_type);
5846 f.write_str(" ");
5847 f.write_node(&display::comma_separated(names));
5848 }
5849 },
5850 GrantTargetSpecification::System => f.write_str("SYSTEM"),
5851 }
5852 }
5853}
5854impl_display_t!(GrantTargetSpecification);
5855
5856#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5858pub struct GrantPrivilegesStatement<T: AstInfo> {
5859 pub privileges: PrivilegeSpecification,
5861 pub target: GrantTargetSpecification<T>,
5863 pub roles: Vec<T::RoleName>,
5865}
5866
5867impl<T: AstInfo> AstDisplay for GrantPrivilegesStatement<T> {
5868 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5869 f.write_str("GRANT ");
5870 f.write_node(&self.privileges);
5871 f.write_str(" ON ");
5872 f.write_node(&self.target);
5873 f.write_str(" TO ");
5874 f.write_node(&display::comma_separated(&self.roles));
5875 }
5876}
5877impl_display_t!(GrantPrivilegesStatement);
5878
5879#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5881pub struct RevokePrivilegesStatement<T: AstInfo> {
5882 pub privileges: PrivilegeSpecification,
5884 pub target: GrantTargetSpecification<T>,
5886 pub roles: Vec<T::RoleName>,
5888}
5889
5890impl<T: AstInfo> AstDisplay for RevokePrivilegesStatement<T> {
5891 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5892 f.write_str("REVOKE ");
5893 f.write_node(&self.privileges);
5894 f.write_str(" ON ");
5895 f.write_node(&self.target);
5896 f.write_str(" FROM ");
5897 f.write_node(&display::comma_separated(&self.roles));
5898 }
5899}
5900impl_display_t!(RevokePrivilegesStatement);
5901
5902#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5903pub enum TargetRoleSpecification<T: AstInfo> {
5904 Roles(Vec<T::RoleName>),
5906 AllRoles,
5908}
5909
5910impl<T: AstInfo> AstDisplay for TargetRoleSpecification<T> {
5911 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5912 match self {
5913 TargetRoleSpecification::Roles(roles) => f.write_node(&display::comma_separated(roles)),
5914 TargetRoleSpecification::AllRoles => f.write_str("ALL ROLES"),
5915 }
5916 }
5917}
5918impl_display_t!(TargetRoleSpecification);
5919
5920#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5921pub struct AbbreviatedGrantStatement<T: AstInfo> {
5922 pub privileges: PrivilegeSpecification,
5924 pub object_type: ObjectType,
5928 pub grantees: Vec<T::RoleName>,
5930}
5931
5932impl<T: AstInfo> AstDisplay for AbbreviatedGrantStatement<T> {
5933 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5934 f.write_str("GRANT ");
5935 f.write_node(&self.privileges);
5936 f.write_str(" ON ");
5937 write_grant_object_type_plural(f, &self.object_type);
5938 f.write_str(" TO ");
5939 f.write_node(&display::comma_separated(&self.grantees));
5940 }
5941}
5942impl_display_t!(AbbreviatedGrantStatement);
5943
5944#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5945pub struct AbbreviatedRevokeStatement<T: AstInfo> {
5946 pub privileges: PrivilegeSpecification,
5948 pub object_type: ObjectType,
5952 pub revokees: Vec<T::RoleName>,
5954}
5955
5956impl<T: AstInfo> AstDisplay for AbbreviatedRevokeStatement<T> {
5957 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5958 f.write_str("REVOKE ");
5959 f.write_node(&self.privileges);
5960 f.write_str(" ON ");
5961 write_grant_object_type_plural(f, &self.object_type);
5962 f.write_str(" FROM ");
5963 f.write_node(&display::comma_separated(&self.revokees));
5964 }
5965}
5966impl_display_t!(AbbreviatedRevokeStatement);
5967
5968#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5969pub enum AbbreviatedGrantOrRevokeStatement<T: AstInfo> {
5970 Grant(AbbreviatedGrantStatement<T>),
5971 Revoke(AbbreviatedRevokeStatement<T>),
5972}
5973
5974impl<T: AstInfo> AbbreviatedGrantOrRevokeStatement<T> {
5975 pub fn privileges(&self) -> &PrivilegeSpecification {
5976 match self {
5977 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.privileges,
5978 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.privileges,
5979 }
5980 }
5981
5982 pub fn object_type(&self) -> &ObjectType {
5983 match self {
5984 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.object_type,
5985 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.object_type,
5986 }
5987 }
5988
5989 pub fn roles(&self) -> &Vec<T::RoleName> {
5990 match self {
5991 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.grantees,
5992 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.revokees,
5993 }
5994 }
5995}
5996
5997impl<T: AstInfo> AstDisplay for AbbreviatedGrantOrRevokeStatement<T> {
5998 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5999 match self {
6000 AbbreviatedGrantOrRevokeStatement::Grant(grant) => f.write_node(grant),
6001 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => f.write_node(revoke),
6002 }
6003 }
6004}
6005impl_display_t!(AbbreviatedGrantOrRevokeStatement);
6006
6007#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6009pub struct AlterDefaultPrivilegesStatement<T: AstInfo> {
6010 pub target_roles: TargetRoleSpecification<T>,
6012 pub target_objects: GrantTargetAllSpecification<T>,
6014 pub grant_or_revoke: AbbreviatedGrantOrRevokeStatement<T>,
6016}
6017
6018impl<T: AstInfo> AstDisplay for AlterDefaultPrivilegesStatement<T> {
6019 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
6020 f.write_str("ALTER DEFAULT PRIVILEGES");
6021 match &self.target_roles {
6022 TargetRoleSpecification::Roles(_) => {
6023 f.write_str(" FOR ROLE ");
6024 f.write_node(&self.target_roles);
6025 }
6026 TargetRoleSpecification::AllRoles => {
6027 f.write_str(" FOR ");
6028 f.write_node(&self.target_roles);
6029 }
6030 }
6031 match &self.target_objects {
6032 GrantTargetAllSpecification::All => {}
6033 GrantTargetAllSpecification::AllDatabases { databases } => {
6034 f.write_str(" IN DATABASE ");
6035 f.write_node(&display::comma_separated(databases));
6036 }
6037 GrantTargetAllSpecification::AllSchemas { schemas } => {
6038 f.write_str(" IN SCHEMA ");
6039 f.write_node(&display::comma_separated(schemas));
6040 }
6041 }
6042 f.write_str(" ");
6043 f.write_node(&self.grant_or_revoke);
6044 }
6045}
6046impl_display_t!(AlterDefaultPrivilegesStatement);
6047
6048#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6050pub struct ReassignOwnedStatement<T: AstInfo> {
6051 pub old_roles: Vec<T::RoleName>,
6053 pub new_role: T::RoleName,
6055}
6056
6057impl<T: AstInfo> AstDisplay for ReassignOwnedStatement<T> {
6058 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
6059 f.write_str("REASSIGN OWNED BY ");
6060 f.write_node(&display::comma_separated(&self.old_roles));
6061 f.write_str(" TO ");
6062 f.write_node(&self.new_role);
6063 }
6064}
6065impl_display_t!(ReassignOwnedStatement);
6066
6067#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6069pub struct CommentStatement<T: AstInfo> {
6070 pub object: CommentObjectType<T>,
6071 pub comment: Option<String>,
6072}
6073
6074impl<T: AstInfo> AstDisplay for CommentStatement<T> {
6075 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
6076 f.write_str("COMMENT ON ");
6077 f.write_node(&self.object);
6078
6079 f.write_str(" IS ");
6080 match &self.comment {
6081 Some(s) => {
6082 if f.redacted() {
6083 f.write_str("'<REDACTED>'");
6086 } else {
6087 f.write_str("'");
6088 f.write_node(&display::escape_single_quote_string(s));
6089 f.write_str("'");
6090 }
6091 }
6092 None => f.write_str("NULL"),
6093 }
6094 }
6095}
6096impl_display_t!(CommentStatement);
6097
6098#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
6099pub struct ColumnName<T: AstInfo> {
6100 pub relation: T::ItemName,
6101 pub column: T::ColumnReference,
6102}
6103
6104impl<T: AstInfo> AstDisplay for ColumnName<T> {
6105 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
6106 f.write_node(&self.relation);
6107 f.write_str(".");
6108 f.write_node(&self.column);
6109 }
6110}
6111impl_display_t!(ColumnName);
6112
6113#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6114pub enum CommentObjectType<T: AstInfo> {
6115 Table { name: T::ItemName },
6116 View { name: T::ItemName },
6117 Column { name: ColumnName<T> },
6118 MaterializedView { name: T::ItemName },
6119 Source { name: T::ItemName },
6120 Sink { name: T::ItemName },
6121 Index { name: T::ItemName },
6122 Func { name: T::ItemName },
6123 Connection { name: T::ItemName },
6124 Type { ty: T::DataType },
6125 Secret { name: T::ItemName },
6126 Role { name: T::RoleName },
6127 Database { name: T::DatabaseName },
6128 Schema { name: T::SchemaName },
6129 Cluster { name: T::ClusterName },
6130 ClusterReplica { name: QualifiedReplica },
6131 NetworkPolicy { name: T::NetworkPolicyName },
6132}
6133
6134impl<T: AstInfo> AstDisplay for CommentObjectType<T> {
6135 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
6136 use CommentObjectType::*;
6137
6138 match self {
6139 Table { name } => {
6140 f.write_str("TABLE ");
6141 f.write_node(name);
6142 }
6143 View { name } => {
6144 f.write_str("VIEW ");
6145 f.write_node(name);
6146 }
6147 Column { name } => {
6148 f.write_str("COLUMN ");
6149 f.write_node(name);
6150 }
6151 MaterializedView { name } => {
6152 f.write_str("MATERIALIZED VIEW ");
6153 f.write_node(name);
6154 }
6155 Source { name } => {
6156 f.write_str("SOURCE ");
6157 f.write_node(name);
6158 }
6159 Sink { name } => {
6160 f.write_str("SINK ");
6161 f.write_node(name);
6162 }
6163 Index { name } => {
6164 f.write_str("INDEX ");
6165 f.write_node(name);
6166 }
6167 Func { name } => {
6168 f.write_str("FUNCTION ");
6169 f.write_node(name);
6170 }
6171 Connection { name } => {
6172 f.write_str("CONNECTION ");
6173 f.write_node(name);
6174 }
6175 Type { ty } => {
6176 f.write_str("TYPE ");
6177 f.write_node(ty);
6178 }
6179 Secret { name } => {
6180 f.write_str("SECRET ");
6181 f.write_node(name);
6182 }
6183 Role { name } => {
6184 f.write_str("ROLE ");
6185 f.write_node(name);
6186 }
6187 Database { name } => {
6188 f.write_str("DATABASE ");
6189 f.write_node(name);
6190 }
6191 Schema { name } => {
6192 f.write_str("SCHEMA ");
6193 f.write_node(name);
6194 }
6195 Cluster { name } => {
6196 f.write_str("CLUSTER ");
6197 f.write_node(name);
6198 }
6199 ClusterReplica { name } => {
6200 f.write_str("CLUSTER REPLICA ");
6201 f.write_node(name);
6202 }
6203 NetworkPolicy { name } => {
6204 f.write_str("NETWORK POLICY ");
6205 f.write_node(name);
6206 }
6207 }
6208 }
6209}
6210
6211impl_display_t!(CommentObjectType);
6212
6213include!(concat!(env!("OUT_DIR"), "/display.simple_options.rs"));