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