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 => unreachable!(),
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 f.write_str(", ");
1773 f.write_node(&display::comma_separated(constraints));
1774 }
1775 f.write_str(")");
1776 }
1777 f.write_str(" FROM SOURCE ");
1778 f.write_node(source);
1779 if let Some(external_reference) = external_reference {
1780 f.write_str(" (REFERENCE = ");
1781 f.write_node(external_reference);
1782 f.write_str(")");
1783 }
1784
1785 if let Some(format) = &format {
1786 f.write_str(" ");
1787 f.write_node(format);
1788 }
1789 if !include_metadata.is_empty() {
1790 f.write_str(" INCLUDE ");
1791 f.write_node(&display::comma_separated(include_metadata));
1792 }
1793 if let Some(envelope) = &envelope {
1794 f.write_str(" ENVELOPE ");
1795 f.write_node(envelope);
1796 }
1797 if !with_options.is_empty() {
1798 f.write_str(" WITH (");
1799 f.write_node(&display::comma_separated(with_options));
1800 f.write_str(")");
1801 }
1802 }
1803}
1804impl_display_t!(CreateTableFromSourceStatement);
1805
1806#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1808pub struct CreateIndexStatement<T: AstInfo> {
1809 pub name: Option<Ident>,
1811 pub in_cluster: Option<T::ClusterName>,
1812 pub on_name: T::ItemName,
1814 pub key_parts: Option<Vec<Expr<T>>>,
1817 pub with_options: Vec<IndexOption<T>>,
1818 pub if_not_exists: bool,
1819}
1820
1821impl<T: AstInfo> AstDisplay for CreateIndexStatement<T> {
1822 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1823 f.write_str("CREATE ");
1824 if self.key_parts.is_none() {
1825 f.write_str("DEFAULT ");
1826 }
1827 f.write_str("INDEX ");
1828 if self.if_not_exists {
1829 f.write_str("IF NOT EXISTS ");
1830 }
1831 if let Some(name) = &self.name {
1832 f.write_node(name);
1833 f.write_str(" ");
1834 }
1835 if let Some(cluster) = &self.in_cluster {
1836 f.write_str("IN CLUSTER ");
1837 f.write_node(cluster);
1838 f.write_str(" ");
1839 }
1840 f.write_str("ON ");
1841 f.write_node(&self.on_name);
1842 if let Some(key_parts) = &self.key_parts {
1843 f.write_str(" (");
1844 f.write_node(&display::comma_separated(key_parts));
1845 f.write_str(")");
1846 }
1847 if !self.with_options.is_empty() {
1848 f.write_str(" WITH (");
1849 f.write_node(&display::comma_separated(&self.with_options));
1850 f.write_str(")");
1851 }
1852 }
1853}
1854impl_display_t!(CreateIndexStatement);
1855
1856#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1858pub enum IndexOptionName {
1859 RetainHistory,
1861}
1862
1863impl AstDisplay for IndexOptionName {
1864 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1865 match self {
1866 IndexOptionName::RetainHistory => {
1867 f.write_str("RETAIN HISTORY");
1868 }
1869 }
1870 }
1871}
1872
1873impl WithOptionName for IndexOptionName {
1874 fn redact_value(&self) -> bool {
1880 match self {
1881 IndexOptionName::RetainHistory => false,
1882 }
1883 }
1884}
1885
1886#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1887pub struct IndexOption<T: AstInfo> {
1888 pub name: IndexOptionName,
1889 pub value: Option<WithOptionValue<T>>,
1890}
1891impl_display_for_with_option!(IndexOption);
1892
1893#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1895pub struct CreateRoleStatement {
1896 pub name: Ident,
1898 pub options: Vec<RoleAttribute>,
1900}
1901
1902impl AstDisplay for CreateRoleStatement {
1903 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1904 f.write_str("CREATE ");
1905 f.write_str("ROLE ");
1906 f.write_node(&self.name);
1907 for option in &self.options {
1908 f.write_str(" ");
1909 option.fmt(f)
1910 }
1911 }
1912}
1913impl_display!(CreateRoleStatement);
1914
1915#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1917pub enum RoleAttribute {
1918 Inherit,
1920 NoInherit,
1922 Password(Option<String>),
1924 Login,
1926 NoLogin,
1927 SuperUser,
1928 NoSuperUser,
1929 CreateCluster,
1930 NoCreateCluster,
1931 CreateDB,
1932 NoCreateDB,
1933 CreateRole,
1934 NoCreateRole,
1935}
1936
1937impl AstDisplay for RoleAttribute {
1938 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1939 match self {
1940 RoleAttribute::SuperUser => f.write_str("SUPERUSER"),
1941 RoleAttribute::NoSuperUser => f.write_str("NOSUPERUSER"),
1942 RoleAttribute::Login => f.write_str("LOGIN"),
1943 RoleAttribute::NoLogin => f.write_str("NOLOGIN"),
1944 RoleAttribute::Inherit => f.write_str("INHERIT"),
1945 RoleAttribute::NoInherit => f.write_str("NOINHERIT"),
1946 RoleAttribute::CreateCluster => f.write_str("CREATECLUSTER"),
1947 RoleAttribute::NoCreateCluster => f.write_str("NOCREATECLUSTER"),
1948 RoleAttribute::CreateDB => f.write_str("CREATEDB"),
1949 RoleAttribute::NoCreateDB => f.write_str("NOCREATEDB"),
1950 RoleAttribute::CreateRole => f.write_str("CREATEROLE"),
1951 RoleAttribute::NoCreateRole => f.write_str("NOCREATEROLE"),
1952 RoleAttribute::Password(_) => f.write_str("PASSWORD"),
1953 }
1954 }
1955}
1956impl_display!(RoleAttribute);
1957
1958#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1960pub enum SetRoleVar {
1961 Set { name: Ident, value: SetVariableTo },
1963 Reset { name: Ident },
1965}
1966
1967impl AstDisplay for SetRoleVar {
1968 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1969 match self {
1970 SetRoleVar::Set { name, value } => {
1971 f.write_str("SET ");
1972 f.write_node(name);
1973 f.write_str(" = ");
1974 f.write_node(value);
1975 }
1976 SetRoleVar::Reset { name } => {
1977 f.write_str("RESET ");
1978 f.write_node(name);
1979 }
1980 }
1981 }
1982}
1983impl_display!(SetRoleVar);
1984
1985#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1987pub struct AlterNetworkPolicyStatement<T: AstInfo> {
1988 pub name: Ident,
1990 pub options: Vec<NetworkPolicyOption<T>>,
1992}
1993
1994impl<T: AstInfo> AstDisplay for AlterNetworkPolicyStatement<T> {
1995 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
1996 f.write_str("ALTER ");
1997 f.write_str("NETWORK POLICY ");
1998 f.write_node(&self.name);
1999 f.write_str(" SET (");
2000 f.write_node(&display::comma_separated(&self.options));
2001 f.write_str(" )");
2002 }
2003}
2004impl_display_t!(AlterNetworkPolicyStatement);
2005
2006#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2008pub struct CreateNetworkPolicyStatement<T: AstInfo> {
2009 pub name: Ident,
2011 pub options: Vec<NetworkPolicyOption<T>>,
2013}
2014
2015impl<T: AstInfo> AstDisplay for CreateNetworkPolicyStatement<T> {
2016 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2017 f.write_str("CREATE ");
2018 f.write_str("NETWORK POLICY ");
2019 f.write_node(&self.name);
2020 f.write_str(" (");
2021 f.write_node(&display::comma_separated(&self.options));
2022 f.write_str(" )");
2023 }
2024}
2025impl_display_t!(CreateNetworkPolicyStatement);
2026
2027#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2028pub struct NetworkPolicyOption<T: AstInfo> {
2029 pub name: NetworkPolicyOptionName,
2030 pub value: Option<WithOptionValue<T>>,
2031}
2032
2033#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2034pub enum NetworkPolicyOptionName {
2035 Rules,
2036}
2037
2038impl WithOptionName for NetworkPolicyOptionName {
2039 fn redact_value(&self) -> bool {
2045 match self {
2046 NetworkPolicyOptionName::Rules => false,
2047 }
2048 }
2049}
2050
2051impl AstDisplay for NetworkPolicyOptionName {
2052 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2053 match self {
2054 NetworkPolicyOptionName::Rules => f.write_str("RULES"),
2055 }
2056 }
2057}
2058impl_display_for_with_option!(NetworkPolicyOption);
2059
2060#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2061pub struct NetworkPolicyRuleDefinition<T: AstInfo> {
2062 pub name: Ident,
2063 pub options: Vec<NetworkPolicyRuleOption<T>>,
2064}
2065
2066impl<T: AstInfo> AstDisplay for NetworkPolicyRuleDefinition<T> {
2067 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2068 f.write_node(&self.name);
2069 f.write_str(" (");
2070 f.write_node(&display::comma_separated(&self.options));
2071 f.write_str(" )");
2072 }
2073}
2074
2075#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2076pub struct NetworkPolicyRuleOption<T: AstInfo> {
2077 pub name: NetworkPolicyRuleOptionName,
2078 pub value: Option<WithOptionValue<T>>,
2079}
2080
2081#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2082pub enum NetworkPolicyRuleOptionName {
2083 Direction,
2084 Action,
2085 Address,
2086}
2087
2088impl WithOptionName for NetworkPolicyRuleOptionName {
2089 fn redact_value(&self) -> bool {
2095 match self {
2096 NetworkPolicyRuleOptionName::Direction
2097 | NetworkPolicyRuleOptionName::Action
2098 | NetworkPolicyRuleOptionName::Address => false,
2099 }
2100 }
2101}
2102
2103impl AstDisplay for NetworkPolicyRuleOptionName {
2104 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2105 match self {
2106 NetworkPolicyRuleOptionName::Direction => f.write_str("DIRECTION"),
2107 NetworkPolicyRuleOptionName::Action => f.write_str("ACTION"),
2108 NetworkPolicyRuleOptionName::Address => f.write_str("ADDRESS"),
2109 }
2110 }
2111}
2112
2113impl_display_for_with_option!(NetworkPolicyRuleOption);
2114
2115#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2117pub struct CreateSecretStatement<T: AstInfo> {
2118 pub name: UnresolvedItemName,
2119 pub if_not_exists: bool,
2120 pub value: Expr<T>,
2121}
2122
2123impl<T: AstInfo> AstDisplay for CreateSecretStatement<T> {
2124 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2125 f.write_str("CREATE SECRET ");
2126 if self.if_not_exists {
2127 f.write_str("IF NOT EXISTS ");
2128 }
2129 f.write_node(&self.name);
2130 f.write_str(" AS ");
2131
2132 if f.redacted() {
2133 f.write_str("'<REDACTED>'");
2134 } else {
2135 f.write_node(&self.value);
2136 }
2137 }
2138}
2139impl_display_t!(CreateSecretStatement);
2140
2141#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2143pub struct CreateTypeStatement<T: AstInfo> {
2144 pub name: UnresolvedItemName,
2146 pub as_type: CreateTypeAs<T>,
2148}
2149
2150impl<T: AstInfo> AstDisplay for CreateTypeStatement<T> {
2151 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2152 f.write_str("CREATE TYPE ");
2153 f.write_node(&self.name);
2154 f.write_str(" AS ");
2155 match &self.as_type {
2156 CreateTypeAs::List { options } => {
2157 f.write_str(&self.as_type);
2158 f.write_str("(");
2159 if !options.is_empty() {
2160 f.write_node(&display::comma_separated(options));
2161 }
2162 f.write_str(")");
2163 }
2164 CreateTypeAs::Map { options } => {
2165 f.write_str(&self.as_type);
2166 f.write_str("(");
2167 if !options.is_empty() {
2168 f.write_node(&display::comma_separated(options));
2169 }
2170 f.write_str(")");
2171 }
2172 CreateTypeAs::Record { column_defs } => {
2173 f.write_str("(");
2174 if !column_defs.is_empty() {
2175 f.write_node(&display::comma_separated(column_defs));
2176 }
2177 f.write_str(")");
2178 }
2179 };
2180 }
2181}
2182impl_display_t!(CreateTypeStatement);
2183
2184#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2185pub enum ClusterOptionName {
2186 AvailabilityZones,
2188 Disk,
2190 IntrospectionInterval,
2192 IntrospectionDebugging,
2194 Managed,
2196 Replicas,
2198 ReplicationFactor,
2200 Size,
2202 Schedule,
2204 WorkloadClass,
2206}
2207
2208impl AstDisplay for ClusterOptionName {
2209 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2210 match self {
2211 ClusterOptionName::AvailabilityZones => f.write_str("AVAILABILITY ZONES"),
2212 ClusterOptionName::Disk => f.write_str("DISK"),
2213 ClusterOptionName::IntrospectionDebugging => f.write_str("INTROSPECTION DEBUGGING"),
2214 ClusterOptionName::IntrospectionInterval => f.write_str("INTROSPECTION INTERVAL"),
2215 ClusterOptionName::Managed => f.write_str("MANAGED"),
2216 ClusterOptionName::Replicas => f.write_str("REPLICAS"),
2217 ClusterOptionName::ReplicationFactor => f.write_str("REPLICATION FACTOR"),
2218 ClusterOptionName::Size => f.write_str("SIZE"),
2219 ClusterOptionName::Schedule => f.write_str("SCHEDULE"),
2220 ClusterOptionName::WorkloadClass => f.write_str("WORKLOAD CLASS"),
2221 }
2222 }
2223}
2224
2225impl WithOptionName for ClusterOptionName {
2226 fn redact_value(&self) -> bool {
2232 match self {
2233 ClusterOptionName::AvailabilityZones
2234 | ClusterOptionName::Disk
2235 | ClusterOptionName::IntrospectionDebugging
2236 | ClusterOptionName::IntrospectionInterval
2237 | ClusterOptionName::Managed
2238 | ClusterOptionName::Replicas
2239 | ClusterOptionName::ReplicationFactor
2240 | ClusterOptionName::Size
2241 | ClusterOptionName::Schedule
2242 | ClusterOptionName::WorkloadClass => false,
2243 }
2244 }
2245}
2246
2247#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2248pub struct ClusterOption<T: AstInfo> {
2250 pub name: ClusterOptionName,
2251 pub value: Option<WithOptionValue<T>>,
2252}
2253impl_display_for_with_option!(ClusterOption);
2254
2255#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2256pub enum ClusterAlterUntilReadyOptionName {
2257 Timeout,
2258 OnTimeout,
2259}
2260
2261impl AstDisplay for ClusterAlterUntilReadyOptionName {
2262 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2263 match self {
2264 Self::Timeout => f.write_str("TIMEOUT"),
2265 Self::OnTimeout => f.write_str("ON TIMEOUT"),
2266 }
2267 }
2268}
2269
2270impl WithOptionName for ClusterAlterUntilReadyOptionName {
2271 fn redact_value(&self) -> bool {
2277 match self {
2278 ClusterAlterUntilReadyOptionName::Timeout
2279 | ClusterAlterUntilReadyOptionName::OnTimeout => false,
2280 }
2281 }
2282}
2283
2284#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2285pub struct ClusterAlterUntilReadyOption<T: AstInfo> {
2286 pub name: ClusterAlterUntilReadyOptionName,
2287 pub value: Option<WithOptionValue<T>>,
2288}
2289impl_display_for_with_option!(ClusterAlterUntilReadyOption);
2290
2291#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2292pub enum ClusterAlterOptionName {
2293 Wait,
2294}
2295
2296impl AstDisplay for ClusterAlterOptionName {
2297 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2298 match self {
2299 ClusterAlterOptionName::Wait => f.write_str("WAIT"),
2300 }
2301 }
2302}
2303
2304impl WithOptionName for ClusterAlterOptionName {
2305 fn redact_value(&self) -> bool {
2311 match self {
2312 ClusterAlterOptionName::Wait => false,
2313 }
2314 }
2315}
2316
2317#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2318pub enum ClusterAlterOptionValue<T: AstInfo> {
2319 For(Value),
2320 UntilReady(Vec<ClusterAlterUntilReadyOption<T>>),
2321}
2322
2323impl<T: AstInfo> AstDisplay for ClusterAlterOptionValue<T> {
2324 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2325 match self {
2326 ClusterAlterOptionValue::For(duration) => {
2327 f.write_str("FOR ");
2328 f.write_node(duration);
2329 }
2330 ClusterAlterOptionValue::UntilReady(options) => {
2331 f.write_str("UNTIL READY (");
2332 f.write_node(&display::comma_separated(options));
2333 f.write_str(")");
2334 }
2335 }
2336 }
2337}
2338
2339#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2340pub struct ClusterAlterOption<T: AstInfo> {
2342 pub name: ClusterAlterOptionName,
2343 pub value: Option<WithOptionValue<T>>,
2344}
2345
2346impl_display_for_with_option!(ClusterAlterOption);
2347
2348#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2351pub enum ClusterFeatureName {
2352 ReoptimizeImportedViews,
2353 EnableNewOuterJoinLowering,
2354 EnableEagerDeltaJoins,
2355 EnableVariadicLeftJoinLowering,
2356 EnableLetrecFixpointAnalysis,
2357 EnableJoinPrioritizeArranged,
2358 EnableProjectionPushdownAfterRelationCse,
2359}
2360
2361impl WithOptionName for ClusterFeatureName {
2362 fn redact_value(&self) -> bool {
2368 match self {
2369 Self::ReoptimizeImportedViews
2370 | Self::EnableNewOuterJoinLowering
2371 | Self::EnableEagerDeltaJoins
2372 | Self::EnableVariadicLeftJoinLowering
2373 | Self::EnableLetrecFixpointAnalysis
2374 | Self::EnableJoinPrioritizeArranged
2375 | Self::EnableProjectionPushdownAfterRelationCse => false,
2376 }
2377 }
2378}
2379
2380#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2381pub struct ClusterFeature<T: AstInfo> {
2382 pub name: ClusterFeatureName,
2383 pub value: Option<WithOptionValue<T>>,
2384}
2385impl_display_for_with_option!(ClusterFeature);
2386
2387#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2389pub struct CreateClusterStatement<T: AstInfo> {
2390 pub name: Ident,
2392 pub options: Vec<ClusterOption<T>>,
2394 pub features: Vec<ClusterFeature<T>>,
2396}
2397
2398impl<T: AstInfo> AstDisplay for CreateClusterStatement<T> {
2399 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2400 f.write_str("CREATE CLUSTER ");
2401 f.write_node(&self.name);
2402 if !self.options.is_empty() {
2403 f.write_str(" (");
2404 f.write_node(&display::comma_separated(&self.options));
2405 f.write_str(")");
2406 }
2407 if !self.features.is_empty() {
2408 f.write_str(" FEATURES (");
2409 f.write_node(&display::comma_separated(&self.features));
2410 f.write_str(")");
2411 }
2412 }
2413}
2414impl_display_t!(CreateClusterStatement);
2415
2416#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2417pub struct ReplicaDefinition<T: AstInfo> {
2418 pub name: Ident,
2420 pub options: Vec<ReplicaOption<T>>,
2422}
2423
2424impl<T: AstInfo> AstDisplay for ReplicaDefinition<T> {
2427 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2428 f.write_node(&self.name);
2429 f.write_str(" (");
2430 f.write_node(&display::comma_separated(&self.options));
2431 f.write_str(")");
2432 }
2433}
2434impl_display_t!(ReplicaDefinition);
2435
2436#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2437pub enum AlterClusterAction<T: AstInfo> {
2438 SetOptions {
2439 options: Vec<ClusterOption<T>>,
2440 with_options: Vec<ClusterAlterOption<T>>,
2441 },
2442 ResetOptions(Vec<ClusterOptionName>),
2443}
2444
2445#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2447pub struct AlterClusterStatement<T: AstInfo> {
2448 pub if_exists: bool,
2450 pub name: Ident,
2452 pub action: AlterClusterAction<T>,
2454}
2455
2456impl<T: AstInfo> AstDisplay for AlterClusterStatement<T> {
2457 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2458 f.write_str("ALTER CLUSTER ");
2459 if self.if_exists {
2460 f.write_str("IF EXISTS ");
2461 }
2462 f.write_node(&self.name);
2463 f.write_str(" ");
2464 match &self.action {
2465 AlterClusterAction::SetOptions {
2466 options,
2467 with_options,
2468 } => {
2469 f.write_str("SET (");
2470 f.write_node(&display::comma_separated(options));
2471 f.write_str(")");
2472 if !with_options.is_empty() {
2473 f.write_str(" WITH (");
2474 f.write_node(&display::comma_separated(with_options));
2475 f.write_str(")");
2476 }
2477 }
2478 AlterClusterAction::ResetOptions(options) => {
2479 f.write_str("RESET (");
2480 f.write_node(&display::comma_separated(options));
2481 f.write_str(")");
2482 }
2483 }
2484 }
2485}
2486impl_display_t!(AlterClusterStatement);
2487
2488#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2490pub struct CreateClusterReplicaStatement<T: AstInfo> {
2491 pub of_cluster: Ident,
2493 pub definition: ReplicaDefinition<T>,
2495}
2496
2497impl<T: AstInfo> AstDisplay for CreateClusterReplicaStatement<T> {
2498 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2499 f.write_str("CREATE CLUSTER REPLICA ");
2500 f.write_node(&self.of_cluster);
2501 f.write_str(".");
2502 f.write_node(&self.definition.name);
2503 f.write_str(" (");
2504 f.write_node(&display::comma_separated(&self.definition.options));
2505 f.write_str(")");
2506 }
2507}
2508impl_display_t!(CreateClusterReplicaStatement);
2509
2510#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2511pub enum ReplicaOptionName {
2512 BilledAs,
2514 Size,
2516 AvailabilityZone,
2518 StorageAddresses,
2520 StoragectlAddresses,
2522 ComputectlAddresses,
2524 ComputeAddresses,
2526 Workers,
2528 Internal,
2530 IntrospectionInterval,
2532 IntrospectionDebugging,
2534 Disk,
2536}
2537
2538impl AstDisplay for ReplicaOptionName {
2539 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2540 match self {
2541 ReplicaOptionName::BilledAs => f.write_str("BILLED AS"),
2542 ReplicaOptionName::Size => f.write_str("SIZE"),
2543 ReplicaOptionName::AvailabilityZone => f.write_str("AVAILABILITY ZONE"),
2544 ReplicaOptionName::StorageAddresses => f.write_str("STORAGE ADDRESSES"),
2545 ReplicaOptionName::StoragectlAddresses => f.write_str("STORAGECTL ADDRESSES"),
2546 ReplicaOptionName::ComputectlAddresses => f.write_str("COMPUTECTL ADDRESSES"),
2547 ReplicaOptionName::ComputeAddresses => f.write_str("COMPUTE ADDRESSES"),
2548 ReplicaOptionName::Workers => f.write_str("WORKERS"),
2549 ReplicaOptionName::Internal => f.write_str("INTERNAL"),
2550 ReplicaOptionName::IntrospectionInterval => f.write_str("INTROSPECTION INTERVAL"),
2551 ReplicaOptionName::IntrospectionDebugging => f.write_str("INTROSPECTION DEBUGGING"),
2552 ReplicaOptionName::Disk => f.write_str("DISK"),
2553 }
2554 }
2555}
2556
2557impl WithOptionName for ReplicaOptionName {
2558 fn redact_value(&self) -> bool {
2564 match self {
2565 ReplicaOptionName::BilledAs
2566 | ReplicaOptionName::Size
2567 | ReplicaOptionName::AvailabilityZone
2568 | ReplicaOptionName::StorageAddresses
2569 | ReplicaOptionName::StoragectlAddresses
2570 | ReplicaOptionName::ComputectlAddresses
2571 | ReplicaOptionName::ComputeAddresses
2572 | ReplicaOptionName::Workers
2573 | ReplicaOptionName::Internal
2574 | ReplicaOptionName::IntrospectionInterval
2575 | ReplicaOptionName::IntrospectionDebugging
2576 | ReplicaOptionName::Disk => false,
2577 }
2578 }
2579}
2580
2581#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2582pub struct ReplicaOption<T: AstInfo> {
2584 pub name: ReplicaOptionName,
2585 pub value: Option<WithOptionValue<T>>,
2586}
2587impl_display_for_with_option!(ReplicaOption);
2588
2589#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2591pub enum CreateTypeAs<T: AstInfo> {
2592 List {
2593 options: Vec<CreateTypeListOption<T>>,
2594 },
2595 Map {
2596 options: Vec<CreateTypeMapOption<T>>,
2597 },
2598 Record {
2599 column_defs: Vec<ColumnDef<T>>,
2600 },
2601}
2602
2603impl<T: AstInfo> AstDisplay for CreateTypeAs<T> {
2604 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2605 match self {
2606 CreateTypeAs::List { .. } => f.write_str("LIST "),
2607 CreateTypeAs::Map { .. } => f.write_str("MAP "),
2608 CreateTypeAs::Record { .. } => f.write_str("RECORD "),
2609 }
2610 }
2611}
2612impl_display_t!(CreateTypeAs);
2613
2614#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2615pub enum CreateTypeListOptionName {
2616 ElementType,
2617}
2618
2619impl AstDisplay for CreateTypeListOptionName {
2620 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2621 f.write_str(match self {
2622 CreateTypeListOptionName::ElementType => "ELEMENT TYPE",
2623 })
2624 }
2625}
2626
2627impl WithOptionName for CreateTypeListOptionName {
2628 fn redact_value(&self) -> bool {
2634 match self {
2635 CreateTypeListOptionName::ElementType => false,
2636 }
2637 }
2638}
2639
2640#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2641pub struct CreateTypeListOption<T: AstInfo> {
2642 pub name: CreateTypeListOptionName,
2643 pub value: Option<WithOptionValue<T>>,
2644}
2645impl_display_for_with_option!(CreateTypeListOption);
2646
2647#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2648pub enum CreateTypeMapOptionName {
2649 KeyType,
2650 ValueType,
2651}
2652
2653impl AstDisplay for CreateTypeMapOptionName {
2654 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2655 f.write_str(match self {
2656 CreateTypeMapOptionName::KeyType => "KEY TYPE",
2657 CreateTypeMapOptionName::ValueType => "VALUE TYPE",
2658 })
2659 }
2660}
2661
2662impl WithOptionName for CreateTypeMapOptionName {
2663 fn redact_value(&self) -> bool {
2669 match self {
2670 CreateTypeMapOptionName::KeyType | CreateTypeMapOptionName::ValueType => false,
2671 }
2672 }
2673}
2674
2675#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2676pub struct CreateTypeMapOption<T: AstInfo> {
2677 pub name: CreateTypeMapOptionName,
2678 pub value: Option<WithOptionValue<T>>,
2679}
2680impl_display_for_with_option!(CreateTypeMapOption);
2681
2682#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2684pub struct AlterOwnerStatement<T: AstInfo> {
2685 pub object_type: ObjectType,
2686 pub if_exists: bool,
2687 pub name: UnresolvedObjectName,
2688 pub new_owner: T::RoleName,
2689}
2690
2691impl<T: AstInfo> AstDisplay for AlterOwnerStatement<T> {
2692 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2693 f.write_str("ALTER ");
2694 f.write_node(&self.object_type);
2695 f.write_str(" ");
2696 if self.if_exists {
2697 f.write_str("IF EXISTS ");
2698 }
2699 f.write_node(&self.name);
2700 f.write_str(" OWNER TO ");
2701 f.write_node(&self.new_owner);
2702 }
2703}
2704impl_display_t!(AlterOwnerStatement);
2705
2706#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2708pub struct AlterObjectRenameStatement {
2709 pub object_type: ObjectType,
2710 pub if_exists: bool,
2711 pub name: UnresolvedObjectName,
2712 pub to_item_name: Ident,
2713}
2714
2715impl AstDisplay for AlterObjectRenameStatement {
2716 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2717 f.write_str("ALTER ");
2718 f.write_node(&self.object_type);
2719 f.write_str(" ");
2720 if self.if_exists {
2721 f.write_str("IF EXISTS ");
2722 }
2723 f.write_node(&self.name);
2724 f.write_str(" RENAME TO ");
2725 f.write_node(&self.to_item_name);
2726 }
2727}
2728impl_display!(AlterObjectRenameStatement);
2729
2730#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2732pub struct AlterRetainHistoryStatement<T: AstInfo> {
2733 pub object_type: ObjectType,
2734 pub if_exists: bool,
2735 pub name: UnresolvedObjectName,
2736 pub history: Option<WithOptionValue<T>>,
2737}
2738
2739impl<T: AstInfo> AstDisplay for AlterRetainHistoryStatement<T> {
2740 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2741 f.write_str("ALTER ");
2742 f.write_node(&self.object_type);
2743 f.write_str(" ");
2744 if self.if_exists {
2745 f.write_str("IF EXISTS ");
2746 }
2747 f.write_node(&self.name);
2748 if let Some(history) = &self.history {
2749 f.write_str(" SET (RETAIN HISTORY ");
2750 f.write_node(history);
2751 } else {
2752 f.write_str(" RESET (RETAIN HISTORY");
2753 }
2754 f.write_str(")");
2755 }
2756}
2757impl_display_t!(AlterRetainHistoryStatement);
2758
2759#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2761pub struct AlterObjectSwapStatement {
2762 pub object_type: ObjectType,
2763 pub if_exists: bool,
2764 pub name_a: UnresolvedObjectName,
2765 pub name_b: Ident,
2766}
2767
2768impl AstDisplay for AlterObjectSwapStatement {
2769 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2770 f.write_str("ALTER ");
2771
2772 f.write_node(&self.object_type);
2773 f.write_str(" ");
2774 if self.if_exists {
2775 f.write_str("IF EXISTS ");
2776 }
2777 f.write_node(&self.name_a);
2778
2779 f.write_str(" SWAP WITH ");
2780 f.write_node(&self.name_b);
2781 }
2782}
2783impl_display!(AlterObjectSwapStatement);
2784
2785#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2786pub enum AlterIndexAction<T: AstInfo> {
2787 SetOptions(Vec<IndexOption<T>>),
2788 ResetOptions(Vec<IndexOptionName>),
2789}
2790
2791#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2793pub struct AlterIndexStatement<T: AstInfo> {
2794 pub index_name: UnresolvedItemName,
2795 pub if_exists: bool,
2796 pub action: AlterIndexAction<T>,
2797}
2798
2799impl<T: AstInfo> AstDisplay for AlterIndexStatement<T> {
2800 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2801 f.write_str("ALTER INDEX ");
2802 if self.if_exists {
2803 f.write_str("IF EXISTS ");
2804 }
2805 f.write_node(&self.index_name);
2806 f.write_str(" ");
2807
2808 match &self.action {
2809 AlterIndexAction::SetOptions(options) => {
2810 f.write_str("SET (");
2811 f.write_node(&display::comma_separated(options));
2812 f.write_str(")");
2813 }
2814 AlterIndexAction::ResetOptions(options) => {
2815 f.write_str("RESET (");
2816 f.write_node(&display::comma_separated(options));
2817 f.write_str(")");
2818 }
2819 }
2820 }
2821}
2822
2823impl_display_t!(AlterIndexStatement);
2824
2825#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2826pub enum AlterSinkAction<T: AstInfo> {
2827 SetOptions(Vec<CreateSinkOption<T>>),
2828 ResetOptions(Vec<CreateSinkOptionName>),
2829 ChangeRelation(T::ItemName),
2830}
2831
2832#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2833pub struct AlterSinkStatement<T: AstInfo> {
2834 pub sink_name: UnresolvedItemName,
2835 pub if_exists: bool,
2836 pub action: AlterSinkAction<T>,
2837}
2838
2839impl<T: AstInfo> AstDisplay for AlterSinkStatement<T> {
2840 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2841 f.write_str("ALTER SINK ");
2842 if self.if_exists {
2843 f.write_str("IF EXISTS ");
2844 }
2845 f.write_node(&self.sink_name);
2846 f.write_str(" ");
2847
2848 match &self.action {
2849 AlterSinkAction::ChangeRelation(from) => {
2850 f.write_str("SET FROM ");
2851 f.write_node(from);
2852 }
2853 AlterSinkAction::SetOptions(options) => {
2854 f.write_str("SET (");
2855 f.write_node(&display::comma_separated(options));
2856 f.write_str(")");
2857 }
2858 AlterSinkAction::ResetOptions(options) => {
2859 f.write_str("RESET (");
2860 f.write_node(&display::comma_separated(options));
2861 f.write_str(")");
2862 }
2863 }
2864 }
2865}
2866
2867#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2868pub enum AlterSourceAddSubsourceOptionName {
2869 TextColumns,
2871 ExcludeColumns,
2873 Details,
2878}
2879
2880impl AstDisplay for AlterSourceAddSubsourceOptionName {
2881 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2882 f.write_str(match self {
2883 AlterSourceAddSubsourceOptionName::TextColumns => "TEXT COLUMNS",
2884 AlterSourceAddSubsourceOptionName::ExcludeColumns => "EXCLUDE COLUMNS",
2885 AlterSourceAddSubsourceOptionName::Details => "DETAILS",
2886 })
2887 }
2888}
2889impl_display!(AlterSourceAddSubsourceOptionName);
2890
2891impl WithOptionName for AlterSourceAddSubsourceOptionName {
2892 fn redact_value(&self) -> bool {
2898 match self {
2899 AlterSourceAddSubsourceOptionName::Details
2900 | AlterSourceAddSubsourceOptionName::TextColumns
2901 | AlterSourceAddSubsourceOptionName::ExcludeColumns => false,
2902 }
2903 }
2904}
2905
2906#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2907pub struct AlterSourceAddSubsourceOption<T: AstInfo> {
2909 pub name: AlterSourceAddSubsourceOptionName,
2910 pub value: Option<WithOptionValue<T>>,
2911}
2912impl_display_for_with_option!(AlterSourceAddSubsourceOption);
2913impl_display_t!(AlterSourceAddSubsourceOption);
2914
2915#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2916pub enum AlterSourceAction<T: AstInfo> {
2917 SetOptions(Vec<CreateSourceOption<T>>),
2918 ResetOptions(Vec<CreateSourceOptionName>),
2919 AddSubsources {
2920 external_references: Vec<ExternalReferenceExport>,
2921 options: Vec<AlterSourceAddSubsourceOption<T>>,
2922 },
2923 DropSubsources {
2924 if_exists: bool,
2925 cascade: bool,
2926 names: Vec<UnresolvedItemName>,
2927 },
2928 RefreshReferences,
2929}
2930
2931impl<T: AstInfo> AstDisplay for AlterSourceAction<T> {
2932 fn fmt<W>(&self, f: &mut AstFormatter<W>)
2933 where
2934 W: fmt::Write,
2935 {
2936 match &self {
2937 AlterSourceAction::SetOptions(options) => {
2938 f.write_str("SET (");
2939 f.write_node(&display::comma_separated(options));
2940 f.write_str(")");
2941 }
2942 AlterSourceAction::ResetOptions(options) => {
2943 f.write_str("RESET (");
2944 f.write_node(&display::comma_separated(options));
2945 f.write_str(")");
2946 }
2947 AlterSourceAction::DropSubsources {
2948 if_exists,
2949 cascade,
2950 names,
2951 } => {
2952 f.write_str("DROP SUBSOURCE ");
2953 if *if_exists {
2954 f.write_str("IF EXISTS ");
2955 }
2956
2957 f.write_node(&display::comma_separated(names));
2958
2959 if *cascade {
2960 f.write_str(" CASCADE");
2961 }
2962 }
2963 AlterSourceAction::AddSubsources {
2964 external_references: subsources,
2965 options,
2966 } => {
2967 f.write_str("ADD SUBSOURCE ");
2968
2969 f.write_node(&display::comma_separated(subsources));
2970
2971 if !options.is_empty() {
2972 f.write_str(" WITH (");
2973 f.write_node(&display::comma_separated(options));
2974 f.write_str(")");
2975 }
2976 }
2977 AlterSourceAction::RefreshReferences => {
2978 f.write_str("REFRESH REFERENCES");
2979 }
2980 }
2981 }
2982}
2983
2984#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2985pub struct AlterSourceStatement<T: AstInfo> {
2986 pub source_name: UnresolvedItemName,
2987 pub if_exists: bool,
2988 pub action: AlterSourceAction<T>,
2989}
2990
2991impl<T: AstInfo> AstDisplay for AlterSourceStatement<T> {
2992 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2993 f.write_str("ALTER SOURCE ");
2994 if self.if_exists {
2995 f.write_str("IF EXISTS ");
2996 }
2997 f.write_node(&self.source_name);
2998 f.write_str(" ");
2999 f.write_node(&self.action)
3000 }
3001}
3002
3003impl_display_t!(AlterSourceStatement);
3004
3005#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3007pub struct AlterSecretStatement<T: AstInfo> {
3008 pub name: UnresolvedItemName,
3009 pub if_exists: bool,
3010 pub value: Expr<T>,
3011}
3012
3013impl<T: AstInfo> AstDisplay for AlterSecretStatement<T> {
3014 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3015 f.write_str("ALTER SECRET ");
3016 if self.if_exists {
3017 f.write_str("IF EXISTS ");
3018 }
3019 f.write_node(&self.name);
3020 f.write_str(" AS ");
3021
3022 if f.redacted() {
3023 f.write_str("'<REDACTED>'");
3024 } else {
3025 f.write_node(&self.value);
3026 }
3027 }
3028}
3029
3030impl_display_t!(AlterSecretStatement);
3031
3032#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3033pub enum AlterConnectionAction<T: AstInfo> {
3034 RotateKeys,
3035 SetOption(ConnectionOption<T>),
3036 DropOption(ConnectionOptionName),
3037}
3038
3039impl<T: AstInfo> AstDisplay for AlterConnectionAction<T> {
3040 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3041 match self {
3042 AlterConnectionAction::RotateKeys => f.write_str("ROTATE KEYS"),
3043 AlterConnectionAction::SetOption(option) => {
3044 f.write_str("SET (");
3045 f.write_node(option);
3046 f.write_str(")");
3047 }
3048 AlterConnectionAction::DropOption(option) => {
3049 f.write_str("DROP (");
3050 f.write_node(option);
3051 f.write_str(")");
3052 }
3053 }
3054 }
3055}
3056impl_display_t!(AlterConnectionAction);
3057
3058#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3059pub enum AlterConnectionOptionName {
3060 Validate,
3061}
3062
3063impl AstDisplay for AlterConnectionOptionName {
3064 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3065 f.write_str(match self {
3066 AlterConnectionOptionName::Validate => "VALIDATE",
3067 })
3068 }
3069}
3070impl_display!(AlterConnectionOptionName);
3071
3072impl WithOptionName for AlterConnectionOptionName {
3073 fn redact_value(&self) -> bool {
3079 match self {
3080 AlterConnectionOptionName::Validate => false,
3081 }
3082 }
3083}
3084
3085#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3086pub struct AlterConnectionOption<T: AstInfo> {
3088 pub name: AlterConnectionOptionName,
3089 pub value: Option<WithOptionValue<T>>,
3090}
3091impl_display_for_with_option!(AlterConnectionOption);
3092impl_display_t!(AlterConnectionOption);
3093
3094#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3096pub struct AlterConnectionStatement<T: AstInfo> {
3097 pub name: UnresolvedItemName,
3098 pub if_exists: bool,
3099 pub actions: Vec<AlterConnectionAction<T>>,
3100 pub with_options: Vec<AlterConnectionOption<T>>,
3101}
3102
3103impl<T: AstInfo> AstDisplay for AlterConnectionStatement<T> {
3104 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3105 f.write_str("ALTER CONNECTION ");
3106 if self.if_exists {
3107 f.write_str("IF EXISTS ");
3108 }
3109 f.write_node(&self.name);
3110 f.write_str(" ");
3111 f.write_node(&display::comma_separated(&self.actions));
3112
3113 if !self.with_options.is_empty() {
3114 f.write_str(" WITH (");
3115 f.write_node(&display::comma_separated(&self.with_options));
3116 f.write_str(")");
3117 }
3118 }
3119}
3120
3121impl_display_t!(AlterConnectionStatement);
3122
3123#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3125pub struct AlterRoleStatement<T: AstInfo> {
3126 pub name: T::RoleName,
3128 pub option: AlterRoleOption,
3130}
3131
3132impl<T: AstInfo> AstDisplay for AlterRoleStatement<T> {
3133 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3134 f.write_str("ALTER ROLE ");
3135 f.write_node(&self.name);
3136 f.write_node(&self.option);
3137 }
3138}
3139impl_display_t!(AlterRoleStatement);
3140
3141#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3143pub enum AlterRoleOption {
3144 Attributes(Vec<RoleAttribute>),
3146 Variable(SetRoleVar),
3148}
3149
3150impl AstDisplay for AlterRoleOption {
3151 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3152 match self {
3153 AlterRoleOption::Attributes(attrs) => {
3154 for attr in attrs {
3155 f.write_str(" ");
3156 attr.fmt(f)
3157 }
3158 }
3159 AlterRoleOption::Variable(var) => {
3160 f.write_str(" ");
3161 f.write_node(var);
3162 }
3163 }
3164 }
3165}
3166impl_display!(AlterRoleOption);
3167
3168#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3170pub struct AlterTableAddColumnStatement<T: AstInfo> {
3171 pub if_exists: bool,
3172 pub name: UnresolvedItemName,
3173 pub if_col_not_exist: bool,
3174 pub column_name: Ident,
3175 pub data_type: T::DataType,
3176}
3177
3178impl<T: AstInfo> AstDisplay for AlterTableAddColumnStatement<T> {
3179 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3180 where
3181 W: fmt::Write,
3182 {
3183 f.write_str("ALTER TABLE ");
3184 if self.if_exists {
3185 f.write_str("IF EXISTS ");
3186 }
3187 f.write_node(&self.name);
3188
3189 f.write_str(" ADD COLUMN ");
3190 if self.if_col_not_exist {
3191 f.write_str("IF NOT EXISTS ");
3192 }
3193
3194 f.write_node(&self.column_name);
3195 f.write_str(" ");
3196 f.write_node(&self.data_type);
3197 }
3198}
3199
3200impl_display_t!(AlterTableAddColumnStatement);
3201
3202#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3204pub struct AlterMaterializedViewApplyReplacementStatement {
3205 pub if_exists: bool,
3206 pub name: UnresolvedItemName,
3207 pub replacement_name: UnresolvedItemName,
3208}
3209
3210impl AstDisplay for AlterMaterializedViewApplyReplacementStatement {
3211 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3212 where
3213 W: fmt::Write,
3214 {
3215 f.write_str("ALTER MATERIALIZED VIEW ");
3216 if self.if_exists {
3217 f.write_str("IF EXISTS ");
3218 }
3219 f.write_node(&self.name);
3220
3221 f.write_str(" APPLY REPLACEMENT ");
3222 f.write_node(&self.replacement_name);
3223 }
3224}
3225
3226impl_display!(AlterMaterializedViewApplyReplacementStatement);
3227
3228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3229pub struct DiscardStatement {
3230 pub target: DiscardTarget,
3231}
3232
3233impl AstDisplay for DiscardStatement {
3234 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3235 f.write_str("DISCARD ");
3236 f.write_node(&self.target);
3237 }
3238}
3239impl_display!(DiscardStatement);
3240
3241#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3242pub enum DiscardTarget {
3243 Plans,
3244 Sequences,
3245 Temp,
3246 All,
3247}
3248
3249impl AstDisplay for DiscardTarget {
3250 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3251 match self {
3252 DiscardTarget::Plans => f.write_str("PLANS"),
3253 DiscardTarget::Sequences => f.write_str("SEQUENCES"),
3254 DiscardTarget::Temp => f.write_str("TEMP"),
3255 DiscardTarget::All => f.write_str("ALL"),
3256 }
3257 }
3258}
3259impl_display!(DiscardTarget);
3260
3261#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3263pub struct DropObjectsStatement {
3264 pub object_type: ObjectType,
3266 pub if_exists: bool,
3268 pub names: Vec<UnresolvedObjectName>,
3270 pub cascade: bool,
3273}
3274
3275impl AstDisplay for DropObjectsStatement {
3276 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3277 f.write_str("DROP ");
3278 f.write_node(&self.object_type);
3279 f.write_str(" ");
3280 if self.if_exists {
3281 f.write_str("IF EXISTS ");
3282 }
3283 f.write_node(&display::comma_separated(&self.names));
3284 if self.cascade && self.object_type != ObjectType::Database {
3285 f.write_str(" CASCADE");
3286 } else if !self.cascade && self.object_type == ObjectType::Database {
3287 f.write_str(" RESTRICT");
3288 }
3289 }
3290}
3291impl_display!(DropObjectsStatement);
3292
3293#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3295pub struct DropOwnedStatement<T: AstInfo> {
3296 pub role_names: Vec<T::RoleName>,
3298 pub cascade: Option<bool>,
3301}
3302
3303impl<T: AstInfo> DropOwnedStatement<T> {
3304 pub fn cascade(&self) -> bool {
3305 self.cascade == Some(true)
3306 }
3307}
3308
3309impl<T: AstInfo> AstDisplay for DropOwnedStatement<T> {
3310 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3311 f.write_str("DROP OWNED BY ");
3312 f.write_node(&display::comma_separated(&self.role_names));
3313 if let Some(true) = self.cascade {
3314 f.write_str(" CASCADE");
3315 } else if let Some(false) = self.cascade {
3316 f.write_str(" RESTRICT");
3317 }
3318 }
3319}
3320impl_display_t!(DropOwnedStatement);
3321
3322#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3323pub struct QualifiedReplica {
3324 pub cluster: Ident,
3325 pub replica: Ident,
3326}
3327
3328impl AstDisplay for QualifiedReplica {
3329 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3330 f.write_node(&self.cluster);
3331 f.write_str(".");
3332 f.write_node(&self.replica);
3333 }
3334}
3335impl_display!(QualifiedReplica);
3336
3337#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3343pub struct SetVariableStatement {
3344 pub local: bool,
3345 pub variable: Ident,
3346 pub to: SetVariableTo,
3347}
3348
3349impl AstDisplay for SetVariableStatement {
3350 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3351 f.write_str("SET ");
3352 if self.local {
3353 f.write_str("LOCAL ");
3354 }
3355 f.write_node(&self.variable);
3356 f.write_str(" = ");
3357 f.write_node(&self.to);
3358 }
3359}
3360impl_display!(SetVariableStatement);
3361
3362#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3367pub struct ResetVariableStatement {
3368 pub variable: Ident,
3369}
3370
3371impl AstDisplay for ResetVariableStatement {
3372 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3373 f.write_str("RESET ");
3374 f.write_node(&self.variable);
3375 }
3376}
3377impl_display!(ResetVariableStatement);
3378
3379#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3381pub struct ShowVariableStatement {
3382 pub variable: Ident,
3383}
3384
3385impl AstDisplay for ShowVariableStatement {
3386 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3387 f.write_str("SHOW ");
3388 f.write_node(&self.variable);
3389 }
3390}
3391impl_display!(ShowVariableStatement);
3392
3393#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3395pub struct InspectShardStatement {
3396 pub id: String,
3397}
3398
3399impl AstDisplay for InspectShardStatement {
3400 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3401 f.write_str("INSPECT SHARD ");
3402 f.write_str("'");
3403 f.write_node(&display::escape_single_quote_string(&self.id));
3404 f.write_str("'");
3405 }
3406}
3407impl_display!(InspectShardStatement);
3408
3409#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3410pub enum ShowObjectType<T: AstInfo> {
3411 MaterializedView {
3412 in_cluster: Option<T::ClusterName>,
3413 },
3414 Index {
3415 in_cluster: Option<T::ClusterName>,
3416 on_object: Option<T::ItemName>,
3417 },
3418 Table {
3419 on_source: Option<T::ItemName>,
3420 },
3421 View,
3422 Source {
3423 in_cluster: Option<T::ClusterName>,
3424 },
3425 Sink {
3426 in_cluster: Option<T::ClusterName>,
3427 },
3428 Type,
3429 Role,
3430 Cluster,
3431 ClusterReplica,
3432 Object,
3433 Secret,
3434 Connection,
3435 Database,
3436 Schema {
3437 from: Option<T::DatabaseName>,
3438 },
3439 Subsource {
3440 on_source: Option<T::ItemName>,
3441 },
3442 Privileges {
3443 object_type: Option<SystemObjectType>,
3444 role: Option<T::RoleName>,
3445 },
3446 DefaultPrivileges {
3447 object_type: Option<ObjectType>,
3448 role: Option<T::RoleName>,
3449 },
3450 RoleMembership {
3451 role: Option<T::RoleName>,
3452 },
3453 NetworkPolicy,
3454}
3455#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3464pub struct ShowObjectsStatement<T: AstInfo> {
3465 pub object_type: ShowObjectType<T>,
3466 pub from: Option<T::SchemaName>,
3467 pub filter: Option<ShowStatementFilter<T>>,
3468}
3469
3470impl<T: AstInfo> AstDisplay for ShowObjectsStatement<T> {
3471 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3472 f.write_str("SHOW");
3473 f.write_str(" ");
3474
3475 f.write_str(match &self.object_type {
3476 ShowObjectType::Table { .. } => "TABLES",
3477 ShowObjectType::View => "VIEWS",
3478 ShowObjectType::Source { .. } => "SOURCES",
3479 ShowObjectType::Sink { .. } => "SINKS",
3480 ShowObjectType::Type => "TYPES",
3481 ShowObjectType::Role => "ROLES",
3482 ShowObjectType::Cluster => "CLUSTERS",
3483 ShowObjectType::ClusterReplica => "CLUSTER REPLICAS",
3484 ShowObjectType::Object => "OBJECTS",
3485 ShowObjectType::Secret => "SECRETS",
3486 ShowObjectType::Connection => "CONNECTIONS",
3487 ShowObjectType::MaterializedView { .. } => "MATERIALIZED VIEWS",
3488 ShowObjectType::Index { .. } => "INDEXES",
3489 ShowObjectType::Database => "DATABASES",
3490 ShowObjectType::Schema { .. } => "SCHEMAS",
3491 ShowObjectType::Subsource { .. } => "SUBSOURCES",
3492 ShowObjectType::Privileges { .. } => "PRIVILEGES",
3493 ShowObjectType::DefaultPrivileges { .. } => "DEFAULT PRIVILEGES",
3494 ShowObjectType::RoleMembership { .. } => "ROLE MEMBERSHIP",
3495 ShowObjectType::NetworkPolicy => "NETWORK POLICIES",
3496 });
3497
3498 if let ShowObjectType::Index { on_object, .. } = &self.object_type {
3499 if let Some(on_object) = on_object {
3500 f.write_str(" ON ");
3501 f.write_node(on_object);
3502 }
3503 }
3504
3505 if let ShowObjectType::Schema { from: Some(from) } = &self.object_type {
3506 f.write_str(" FROM ");
3507 f.write_node(from);
3508 }
3509
3510 if let Some(from) = &self.from {
3511 f.write_str(" FROM ");
3512 f.write_node(from);
3513 }
3514
3515 match &self.object_type {
3517 ShowObjectType::MaterializedView { in_cluster }
3518 | ShowObjectType::Index { in_cluster, .. }
3519 | ShowObjectType::Sink { in_cluster }
3520 | ShowObjectType::Source { in_cluster } => {
3521 if let Some(cluster) = in_cluster {
3522 f.write_str(" IN CLUSTER ");
3523 f.write_node(cluster);
3524 }
3525 }
3526 _ => (),
3527 }
3528
3529 if let ShowObjectType::Subsource { on_source } = &self.object_type {
3530 if let Some(on_source) = on_source {
3531 f.write_str(" ON ");
3532 f.write_node(on_source);
3533 }
3534 }
3535
3536 if let ShowObjectType::Table { on_source } = &self.object_type {
3537 if let Some(on_source) = on_source {
3538 f.write_str(" ON ");
3539 f.write_node(on_source);
3540 }
3541 }
3542
3543 if let ShowObjectType::Privileges { object_type, role } = &self.object_type {
3544 if let Some(object_type) = object_type {
3545 f.write_str(" ON ");
3546 f.write_node(object_type);
3547 if let SystemObjectType::Object(_) = object_type {
3548 f.write_str("S");
3549 }
3550 }
3551 if let Some(role) = role {
3552 f.write_str(" FOR ");
3553 f.write_node(role);
3554 }
3555 }
3556
3557 if let ShowObjectType::DefaultPrivileges { object_type, role } = &self.object_type {
3558 if let Some(object_type) = object_type {
3559 f.write_str(" ON ");
3560 f.write_node(object_type);
3561 f.write_str("S");
3562 }
3563 if let Some(role) = role {
3564 f.write_str(" FOR ");
3565 f.write_node(role);
3566 }
3567 }
3568
3569 if let ShowObjectType::RoleMembership {
3570 role: Some(role), ..
3571 } = &self.object_type
3572 {
3573 f.write_str(" FOR ");
3574 f.write_node(role);
3575 }
3576
3577 if let Some(filter) = &self.filter {
3578 f.write_str(" ");
3579 f.write_node(filter);
3580 }
3581 }
3582}
3583impl_display_t!(ShowObjectsStatement);
3584
3585#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3589pub struct ShowColumnsStatement<T: AstInfo> {
3590 pub table_name: T::ItemName,
3591 pub filter: Option<ShowStatementFilter<T>>,
3592}
3593
3594impl<T: AstInfo> AstDisplay for ShowColumnsStatement<T> {
3595 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3596 f.write_str("SHOW ");
3597 f.write_str("COLUMNS FROM ");
3598 f.write_node(&self.table_name);
3599 if let Some(filter) = &self.filter {
3600 f.write_str(" ");
3601 f.write_node(filter);
3602 }
3603 }
3604}
3605impl_display_t!(ShowColumnsStatement);
3606
3607#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3609pub struct ShowCreateViewStatement<T: AstInfo> {
3610 pub view_name: T::ItemName,
3611 pub redacted: bool,
3612}
3613
3614impl<T: AstInfo> AstDisplay for ShowCreateViewStatement<T> {
3615 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3616 f.write_str("SHOW ");
3617 if self.redacted {
3618 f.write_str("REDACTED ");
3619 }
3620 f.write_str("CREATE VIEW ");
3621 f.write_node(&self.view_name);
3622 }
3623}
3624impl_display_t!(ShowCreateViewStatement);
3625
3626#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3628pub struct ShowCreateMaterializedViewStatement<T: AstInfo> {
3629 pub materialized_view_name: T::ItemName,
3630 pub redacted: bool,
3631}
3632
3633impl<T: AstInfo> AstDisplay for ShowCreateMaterializedViewStatement<T> {
3634 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3635 f.write_str("SHOW ");
3636 if self.redacted {
3637 f.write_str("REDACTED ");
3638 }
3639 f.write_str("CREATE MATERIALIZED VIEW ");
3640 f.write_node(&self.materialized_view_name);
3641 }
3642}
3643impl_display_t!(ShowCreateMaterializedViewStatement);
3644
3645#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3647pub struct ShowCreateSourceStatement<T: AstInfo> {
3648 pub source_name: T::ItemName,
3649 pub redacted: bool,
3650}
3651
3652impl<T: AstInfo> AstDisplay for ShowCreateSourceStatement<T> {
3653 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3654 f.write_str("SHOW ");
3655 if self.redacted {
3656 f.write_str("REDACTED ");
3657 }
3658 f.write_str("CREATE SOURCE ");
3659 f.write_node(&self.source_name);
3660 }
3661}
3662impl_display_t!(ShowCreateSourceStatement);
3663
3664#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3666pub struct ShowCreateTableStatement<T: AstInfo> {
3667 pub table_name: T::ItemName,
3668 pub redacted: bool,
3669}
3670
3671impl<T: AstInfo> AstDisplay for ShowCreateTableStatement<T> {
3672 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3673 f.write_str("SHOW ");
3674 if self.redacted {
3675 f.write_str("REDACTED ");
3676 }
3677 f.write_str("CREATE TABLE ");
3678 f.write_node(&self.table_name);
3679 }
3680}
3681impl_display_t!(ShowCreateTableStatement);
3682
3683#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3685pub struct ShowCreateSinkStatement<T: AstInfo> {
3686 pub sink_name: T::ItemName,
3687 pub redacted: bool,
3688}
3689
3690impl<T: AstInfo> AstDisplay for ShowCreateSinkStatement<T> {
3691 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3692 f.write_str("SHOW ");
3693 if self.redacted {
3694 f.write_str("REDACTED ");
3695 }
3696 f.write_str("CREATE SINK ");
3697 f.write_node(&self.sink_name);
3698 }
3699}
3700impl_display_t!(ShowCreateSinkStatement);
3701
3702#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3704pub struct ShowCreateIndexStatement<T: AstInfo> {
3705 pub index_name: T::ItemName,
3706 pub redacted: bool,
3707}
3708
3709impl<T: AstInfo> AstDisplay for ShowCreateIndexStatement<T> {
3710 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3711 f.write_str("SHOW ");
3712 if self.redacted {
3713 f.write_str("REDACTED ");
3714 }
3715 f.write_str("CREATE INDEX ");
3716 f.write_node(&self.index_name);
3717 }
3718}
3719impl_display_t!(ShowCreateIndexStatement);
3720
3721#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3723pub struct ShowCreateConnectionStatement<T: AstInfo> {
3724 pub connection_name: T::ItemName,
3725 pub redacted: bool,
3726}
3727
3728impl<T: AstInfo> AstDisplay for ShowCreateConnectionStatement<T> {
3729 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3730 f.write_str("SHOW ");
3731 if self.redacted {
3732 f.write_str("REDACTED ");
3733 }
3734 f.write_str("CREATE CONNECTION ");
3735 f.write_node(&self.connection_name);
3736 }
3737}
3738
3739#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3740pub struct ShowCreateClusterStatement<T: AstInfo> {
3741 pub cluster_name: T::ClusterName,
3742}
3743
3744impl<T: AstInfo> AstDisplay for ShowCreateClusterStatement<T> {
3745 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3746 f.write_str("SHOW CREATE CLUSTER ");
3747 f.write_node(&self.cluster_name);
3748 }
3749}
3750
3751#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3753pub struct StartTransactionStatement {
3754 pub modes: Vec<TransactionMode>,
3755}
3756
3757impl AstDisplay for StartTransactionStatement {
3758 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3759 f.write_str("START TRANSACTION");
3760 if !self.modes.is_empty() {
3761 f.write_str(" ");
3762 f.write_node(&display::comma_separated(&self.modes));
3763 }
3764 }
3765}
3766impl_display!(StartTransactionStatement);
3767
3768#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3770pub struct ShowCreateTypeStatement<T: AstInfo> {
3771 pub type_name: T::DataType,
3772 pub redacted: bool,
3773}
3774
3775impl<T: AstInfo> AstDisplay for ShowCreateTypeStatement<T> {
3776 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3777 f.write_str("SHOW ");
3778 if self.redacted {
3779 f.write_str("REDACTED ");
3780 }
3781 f.write_str("CREATE TYPE ");
3782 f.write_node(&self.type_name);
3783 }
3784}
3785
3786#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3788pub struct SetTransactionStatement {
3789 pub local: bool,
3790 pub modes: Vec<TransactionMode>,
3791}
3792
3793impl AstDisplay for SetTransactionStatement {
3794 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3795 f.write_str("SET ");
3796 if !self.local {
3797 f.write_str("SESSION CHARACTERISTICS AS ");
3798 }
3799 f.write_str("TRANSACTION");
3800 if !self.modes.is_empty() {
3801 f.write_str(" ");
3802 f.write_node(&display::comma_separated(&self.modes));
3803 }
3804 }
3805}
3806impl_display!(SetTransactionStatement);
3807
3808#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3810pub struct CommitStatement {
3811 pub chain: bool,
3812}
3813
3814impl AstDisplay for CommitStatement {
3815 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3816 f.write_str("COMMIT");
3817 if self.chain {
3818 f.write_str(" AND CHAIN");
3819 }
3820 }
3821}
3822impl_display!(CommitStatement);
3823
3824#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3826pub struct RollbackStatement {
3827 pub chain: bool,
3828}
3829
3830impl AstDisplay for RollbackStatement {
3831 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3832 f.write_str("ROLLBACK");
3833 if self.chain {
3834 f.write_str(" AND CHAIN");
3835 }
3836 }
3837}
3838impl_display!(RollbackStatement);
3839
3840#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3841pub enum SubscribeOptionName {
3842 Snapshot,
3843 Progress,
3844}
3845
3846impl AstDisplay for SubscribeOptionName {
3847 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3848 match self {
3849 SubscribeOptionName::Snapshot => f.write_str("SNAPSHOT"),
3850 SubscribeOptionName::Progress => f.write_str("PROGRESS"),
3851 }
3852 }
3853}
3854impl_display!(SubscribeOptionName);
3855
3856impl WithOptionName for SubscribeOptionName {
3857 fn redact_value(&self) -> bool {
3863 match self {
3864 SubscribeOptionName::Snapshot | SubscribeOptionName::Progress => false,
3865 }
3866 }
3867}
3868
3869#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3870pub struct SubscribeOption<T: AstInfo> {
3871 pub name: SubscribeOptionName,
3872 pub value: Option<WithOptionValue<T>>,
3873}
3874impl_display_for_with_option!(SubscribeOption);
3875impl_display_t!(SubscribeOption);
3876
3877#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3879pub struct SubscribeStatement<T: AstInfo> {
3880 pub relation: SubscribeRelation<T>,
3881 pub options: Vec<SubscribeOption<T>>,
3882 pub as_of: Option<AsOf<T>>,
3883 pub up_to: Option<Expr<T>>,
3884 pub output: SubscribeOutput<T>,
3885}
3886
3887impl<T: AstInfo> AstDisplay for SubscribeStatement<T> {
3888 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3889 f.write_str("SUBSCRIBE ");
3890 f.write_node(&self.relation);
3891 if !self.options.is_empty() {
3892 f.write_str(" WITH (");
3893 f.write_node(&display::comma_separated(&self.options));
3894 f.write_str(")");
3895 }
3896 if let Some(as_of) = &self.as_of {
3897 f.write_str(" ");
3898 f.write_node(as_of);
3899 }
3900 if let Some(up_to) = &self.up_to {
3901 f.write_str(" UP TO ");
3902 f.write_node(up_to);
3903 }
3904 f.write_str(&self.output);
3905 }
3906}
3907impl_display_t!(SubscribeStatement);
3908
3909#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3910pub enum SubscribeRelation<T: AstInfo> {
3911 Name(T::ItemName),
3912 Query(Query<T>),
3913}
3914
3915impl<T: AstInfo> AstDisplay for SubscribeRelation<T> {
3916 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3917 match self {
3918 SubscribeRelation::Name(name) => f.write_node(name),
3919 SubscribeRelation::Query(query) => {
3920 f.write_str("(");
3921 f.write_node(query);
3922 f.write_str(")");
3923 }
3924 }
3925 }
3926}
3927impl_display_t!(SubscribeRelation);
3928
3929#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3930pub struct ExplainPlanStatement<T: AstInfo> {
3931 pub stage: Option<ExplainStage>,
3932 pub with_options: Vec<ExplainPlanOption<T>>,
3933 pub format: Option<ExplainFormat>,
3934 pub explainee: Explainee<T>,
3935}
3936
3937impl<T: AstInfo> ExplainPlanStatement<T> {
3938 pub fn stage(&self) -> ExplainStage {
3939 self.stage.unwrap_or(ExplainStage::PhysicalPlan)
3940 }
3941
3942 pub fn format(&self) -> ExplainFormat {
3943 self.format.unwrap_or(ExplainFormat::Text)
3944 }
3945}
3946
3947impl<T: AstInfo> AstDisplay for ExplainPlanStatement<T> {
3948 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3949 f.write_str("EXPLAIN");
3950 if let Some(stage) = &self.stage {
3951 f.write_str(" ");
3952 f.write_node(stage);
3953 }
3954 if !self.with_options.is_empty() {
3955 f.write_str(" WITH (");
3956 f.write_node(&display::comma_separated(&self.with_options));
3957 f.write_str(")");
3958 }
3959 if let Some(format) = &self.format {
3960 f.write_str(" AS ");
3961 f.write_node(format);
3962 }
3963 if self.stage.is_some() {
3964 f.write_str(" FOR");
3965 }
3966 f.write_str(" ");
3967 f.write_node(&self.explainee);
3968 }
3969}
3970impl_display_t!(ExplainPlanStatement);
3971
3972#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3975pub enum ExplainPlanOptionName {
3976 Arity,
3977 Cardinality,
3978 ColumnNames,
3979 FilterPushdown,
3980 HumanizedExpressions,
3981 JoinImplementations,
3982 Keys,
3983 LinearChains,
3984 NonNegative,
3985 NoFastPath,
3986 NoNotices,
3987 NodeIdentifiers,
3988 RawPlans,
3989 RawSyntax,
3990 Raw, Redacted,
3992 SubtreeSize,
3993 Timing,
3994 Types,
3995 Equivalences,
3996 ReoptimizeImportedViews,
3997 EnableNewOuterJoinLowering,
3998 EnableEagerDeltaJoins,
3999 EnableVariadicLeftJoinLowering,
4000 EnableLetrecFixpointAnalysis,
4001 EnableJoinPrioritizeArranged,
4002 EnableProjectionPushdownAfterRelationCse,
4003}
4004
4005impl WithOptionName for ExplainPlanOptionName {
4006 fn redact_value(&self) -> bool {
4012 match self {
4013 Self::Arity
4014 | Self::Cardinality
4015 | Self::ColumnNames
4016 | Self::FilterPushdown
4017 | Self::HumanizedExpressions
4018 | Self::JoinImplementations
4019 | Self::Keys
4020 | Self::LinearChains
4021 | Self::NonNegative
4022 | Self::NoFastPath
4023 | Self::NoNotices
4024 | Self::NodeIdentifiers
4025 | Self::RawPlans
4026 | Self::RawSyntax
4027 | Self::Raw
4028 | Self::Redacted
4029 | Self::SubtreeSize
4030 | Self::Timing
4031 | Self::Types
4032 | Self::Equivalences
4033 | Self::ReoptimizeImportedViews
4034 | Self::EnableNewOuterJoinLowering
4035 | Self::EnableEagerDeltaJoins
4036 | Self::EnableVariadicLeftJoinLowering
4037 | Self::EnableLetrecFixpointAnalysis
4038 | Self::EnableJoinPrioritizeArranged
4039 | Self::EnableProjectionPushdownAfterRelationCse => false,
4040 }
4041 }
4042}
4043
4044#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4045pub struct ExplainPlanOption<T: AstInfo> {
4046 pub name: ExplainPlanOptionName,
4047 pub value: Option<WithOptionValue<T>>,
4048}
4049impl_display_for_with_option!(ExplainPlanOption);
4050
4051#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4052pub enum ExplainSinkSchemaFor {
4053 Key,
4054 Value,
4055}
4056#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4057pub struct ExplainSinkSchemaStatement<T: AstInfo> {
4058 pub schema_for: ExplainSinkSchemaFor,
4059 pub format: Option<ExplainFormat>,
4060 pub statement: CreateSinkStatement<T>,
4061}
4062
4063impl<T: AstInfo> AstDisplay for ExplainSinkSchemaStatement<T> {
4064 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4065 f.write_str("EXPLAIN ");
4066 match &self.schema_for {
4067 ExplainSinkSchemaFor::Key => f.write_str("KEY"),
4068 ExplainSinkSchemaFor::Value => f.write_str("VALUE"),
4069 }
4070 f.write_str(" SCHEMA");
4071 if let Some(format) = &self.format {
4072 f.write_str(" AS ");
4073 f.write_node(format);
4074 }
4075 f.write_str(" FOR ");
4076 f.write_node(&self.statement);
4077 }
4078}
4079impl_display_t!(ExplainSinkSchemaStatement);
4080
4081#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4082pub struct ExplainPushdownStatement<T: AstInfo> {
4083 pub explainee: Explainee<T>,
4084}
4085
4086impl<T: AstInfo> AstDisplay for ExplainPushdownStatement<T> {
4087 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4088 f.write_str("EXPLAIN FILTER PUSHDOWN FOR ");
4089 f.write_node(&self.explainee);
4090 }
4091}
4092impl_display_t!(ExplainPushdownStatement);
4093
4094#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
4095pub enum ExplainAnalyzeComputationProperty {
4096 Cpu,
4097 Memory,
4098}
4099
4100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4101pub enum ExplainAnalyzeProperty {
4102 Computation(ExplainAnalyzeComputationProperties),
4103 Hints,
4104}
4105
4106#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4107pub struct ExplainAnalyzeComputationProperties {
4108 pub properties: Vec<ExplainAnalyzeComputationProperty>,
4110 pub skew: bool,
4111}
4112#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4113pub struct ExplainAnalyzeObjectStatement<T: AstInfo> {
4114 pub properties: ExplainAnalyzeProperty,
4115 pub explainee: Explainee<T>,
4117 pub as_sql: bool,
4118}
4119
4120impl<T: AstInfo> AstDisplay for ExplainAnalyzeObjectStatement<T> {
4121 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4122 f.write_str("EXPLAIN ANALYZE");
4123 match &self.properties {
4124 ExplainAnalyzeProperty::Computation(ExplainAnalyzeComputationProperties {
4125 properties,
4126 skew,
4127 }) => {
4128 let mut first = true;
4129 for property in properties {
4130 if first {
4131 first = false;
4132 } else {
4133 f.write_str(",");
4134 }
4135 match property {
4136 ExplainAnalyzeComputationProperty::Cpu => f.write_str(" CPU"),
4137 ExplainAnalyzeComputationProperty::Memory => f.write_str(" MEMORY"),
4138 }
4139 }
4140 if *skew {
4141 f.write_str(" WITH SKEW");
4142 }
4143 }
4144 ExplainAnalyzeProperty::Hints => f.write_str(" HINTS"),
4145 }
4146 f.write_str(" FOR ");
4147 f.write_node(&self.explainee);
4148 if self.as_sql {
4149 f.write_str(" AS SQL");
4150 }
4151 }
4152}
4153impl_display_t!(ExplainAnalyzeObjectStatement);
4154
4155#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4156pub struct ExplainAnalyzeClusterStatement {
4157 pub properties: ExplainAnalyzeComputationProperties,
4158 pub as_sql: bool,
4159}
4160
4161impl AstDisplay for ExplainAnalyzeClusterStatement {
4162 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4163 f.write_str("EXPLAIN ANALYZE CLUSTER");
4164
4165 let mut first = true;
4166 for property in &self.properties.properties {
4167 if first {
4168 first = false;
4169 } else {
4170 f.write_str(",");
4171 }
4172 match property {
4173 ExplainAnalyzeComputationProperty::Cpu => f.write_str(" CPU"),
4174 ExplainAnalyzeComputationProperty::Memory => f.write_str(" MEMORY"),
4175 }
4176 }
4177
4178 if self.properties.skew {
4179 f.write_str(" WITH SKEW");
4180 }
4181 if self.as_sql {
4182 f.write_str(" AS SQL");
4183 }
4184 }
4185}
4186impl_display!(ExplainAnalyzeClusterStatement);
4187
4188#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4189pub struct ExplainTimestampStatement<T: AstInfo> {
4190 pub format: Option<ExplainFormat>,
4191 pub select: SelectStatement<T>,
4192}
4193
4194impl<T: AstInfo> ExplainTimestampStatement<T> {
4195 pub fn format(&self) -> ExplainFormat {
4196 self.format.unwrap_or(ExplainFormat::Text)
4197 }
4198}
4199
4200impl<T: AstInfo> AstDisplay for ExplainTimestampStatement<T> {
4201 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4202 f.write_str("EXPLAIN TIMESTAMP");
4203 if let Some(format) = &self.format {
4204 f.write_str(" AS ");
4205 f.write_node(format);
4206 }
4207 f.write_str(" FOR ");
4208 f.write_node(&self.select);
4209 }
4210}
4211impl_display_t!(ExplainTimestampStatement);
4212
4213#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4214pub enum InsertSource<T: AstInfo> {
4215 Query(Query<T>),
4216 DefaultValues,
4217}
4218
4219impl<T: AstInfo> AstDisplay for InsertSource<T> {
4220 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4221 match self {
4222 InsertSource::Query(query) => f.write_node(query),
4223 InsertSource::DefaultValues => f.write_str("DEFAULT VALUES"),
4224 }
4225 }
4226}
4227impl_display_t!(InsertSource);
4228
4229#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
4230pub enum ObjectType {
4231 Table,
4232 View,
4233 MaterializedView,
4234 Source,
4235 Sink,
4236 Index,
4237 Type,
4238 Role,
4239 Cluster,
4240 ClusterReplica,
4241 Secret,
4242 Connection,
4243 Database,
4244 Schema,
4245 Func,
4246 Subsource,
4247 NetworkPolicy,
4248}
4249
4250impl ObjectType {
4251 pub fn lives_in_schema(&self) -> bool {
4252 match self {
4253 ObjectType::Table
4254 | ObjectType::View
4255 | ObjectType::MaterializedView
4256 | ObjectType::Source
4257 | ObjectType::Sink
4258 | ObjectType::Index
4259 | ObjectType::Type
4260 | ObjectType::Secret
4261 | ObjectType::Connection
4262 | ObjectType::Func
4263 | ObjectType::Subsource => true,
4264 ObjectType::Database
4265 | ObjectType::Schema
4266 | ObjectType::Cluster
4267 | ObjectType::ClusterReplica
4268 | ObjectType::Role
4269 | ObjectType::NetworkPolicy => false,
4270 }
4271 }
4272}
4273
4274impl AstDisplay for ObjectType {
4275 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4276 f.write_str(match self {
4277 ObjectType::Table => "TABLE",
4278 ObjectType::View => "VIEW",
4279 ObjectType::MaterializedView => "MATERIALIZED VIEW",
4280 ObjectType::Source => "SOURCE",
4281 ObjectType::Sink => "SINK",
4282 ObjectType::Index => "INDEX",
4283 ObjectType::Type => "TYPE",
4284 ObjectType::Role => "ROLE",
4285 ObjectType::Cluster => "CLUSTER",
4286 ObjectType::ClusterReplica => "CLUSTER REPLICA",
4287 ObjectType::Secret => "SECRET",
4288 ObjectType::Connection => "CONNECTION",
4289 ObjectType::Database => "DATABASE",
4290 ObjectType::Schema => "SCHEMA",
4291 ObjectType::Func => "FUNCTION",
4292 ObjectType::Subsource => "SUBSOURCE",
4293 ObjectType::NetworkPolicy => "NETWORK POLICY",
4294 })
4295 }
4296}
4297impl_display!(ObjectType);
4298
4299#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
4300pub enum SystemObjectType {
4301 System,
4302 Object(ObjectType),
4303}
4304
4305impl AstDisplay for SystemObjectType {
4306 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4307 match self {
4308 SystemObjectType::System => f.write_str("SYSTEM"),
4309 SystemObjectType::Object(object) => f.write_node(object),
4310 }
4311 }
4312}
4313impl_display!(SystemObjectType);
4314
4315#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4316pub enum ShowStatementFilter<T: AstInfo> {
4317 Like(String),
4318 Where(Expr<T>),
4319}
4320
4321impl<T: AstInfo> AstDisplay for ShowStatementFilter<T> {
4322 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4323 use ShowStatementFilter::*;
4324 match self {
4325 Like(pattern) => {
4326 f.write_str("LIKE '");
4327 f.write_node(&display::escape_single_quote_string(pattern));
4328 f.write_str("'");
4329 }
4330 Where(expr) => {
4331 f.write_str("WHERE ");
4332 f.write_node(expr);
4333 }
4334 }
4335 }
4336}
4337impl_display_t!(ShowStatementFilter);
4338
4339#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4340pub enum WithOptionValue<T: AstInfo> {
4341 Value(Value),
4342 DataType(T::DataType),
4343 Secret(T::ItemName),
4344 Item(T::ItemName),
4345 UnresolvedItemName(UnresolvedItemName),
4346 Ident(Ident),
4347 Sequence(Vec<WithOptionValue<T>>),
4348 Map(BTreeMap<String, WithOptionValue<T>>),
4349 Expr(Expr<T>),
4351 ClusterReplicas(Vec<ReplicaDefinition<T>>),
4352 ConnectionKafkaBroker(KafkaBroker<T>),
4353 ConnectionAwsPrivatelink(ConnectionDefaultAwsPrivatelink<T>),
4354 KafkaMatchingBrokerRule(KafkaMatchingBrokerRule<T>),
4355 RetainHistoryFor(Value),
4356 Refresh(RefreshOptionValue<T>),
4357 ClusterScheduleOptionValue(ClusterScheduleOptionValue),
4358 ClusterAlterStrategy(ClusterAlterOptionValue<T>),
4359 NetworkPolicyRules(Vec<NetworkPolicyRuleDefinition<T>>),
4360}
4361
4362impl<T: AstInfo> AstDisplay for WithOptionValue<T> {
4363 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4364 if f.redacted() {
4365 match self {
4368 WithOptionValue::Value(_)
4369 | WithOptionValue::Sequence(_)
4370 | WithOptionValue::Map(_)
4371 | WithOptionValue::RetainHistoryFor(_)
4372 | WithOptionValue::Refresh(_)
4373 | WithOptionValue::Expr(_) => {
4374 }
4376 WithOptionValue::Secret(_) | WithOptionValue::ConnectionKafkaBroker(_) => {
4377 f.write_str("'<REDACTED>'");
4378 return;
4379 }
4380 WithOptionValue::DataType(_)
4381 | WithOptionValue::Item(_)
4382 | WithOptionValue::UnresolvedItemName(_)
4383 | WithOptionValue::Ident(_)
4384 | WithOptionValue::ConnectionAwsPrivatelink(_)
4385 | WithOptionValue::KafkaMatchingBrokerRule(_)
4386 | WithOptionValue::ClusterReplicas(_)
4387 | WithOptionValue::ClusterScheduleOptionValue(_)
4388 | WithOptionValue::ClusterAlterStrategy(_)
4389 | WithOptionValue::NetworkPolicyRules(_) => {
4390 }
4392 }
4393 }
4394 match self {
4395 WithOptionValue::Sequence(values) => {
4396 f.write_str("(");
4397 f.write_node(&display::comma_separated(values));
4398 f.write_str(")");
4399 }
4400 WithOptionValue::Map(values) => {
4401 f.write_str("MAP[");
4402 let len = values.len();
4403 for (i, (key, value)) in values.iter().enumerate() {
4404 f.write_str("'");
4405 f.write_node(&display::escape_single_quote_string(key));
4406 f.write_str("' => ");
4407 f.write_node(value);
4408 if i + 1 < len {
4409 f.write_str(", ");
4410 }
4411 }
4412 f.write_str("]");
4413 }
4414 WithOptionValue::Expr(e) => f.write_node(e),
4415 WithOptionValue::Value(value) => f.write_node(value),
4416 WithOptionValue::DataType(typ) => f.write_node(typ),
4417 WithOptionValue::Secret(name) => {
4418 f.write_str("SECRET ");
4419 f.write_node(name)
4420 }
4421 WithOptionValue::Item(obj) => f.write_node(obj),
4422 WithOptionValue::UnresolvedItemName(r) => f.write_node(r),
4423 WithOptionValue::Ident(r) => f.write_node(r),
4424 WithOptionValue::ClusterReplicas(replicas) => {
4425 f.write_str("(");
4426 f.write_node(&display::comma_separated(replicas));
4427 f.write_str(")");
4428 }
4429 WithOptionValue::NetworkPolicyRules(rules) => {
4430 f.write_str("(");
4431 f.write_node(&display::comma_separated(rules));
4432 f.write_str(")");
4433 }
4434 WithOptionValue::ConnectionAwsPrivatelink(aws_privatelink) => {
4435 f.write_node(aws_privatelink);
4436 }
4437 WithOptionValue::KafkaMatchingBrokerRule(rule) => {
4438 f.write_node(rule);
4439 }
4440 WithOptionValue::ConnectionKafkaBroker(broker) => {
4441 f.write_node(broker);
4442 }
4443 WithOptionValue::RetainHistoryFor(value) => {
4444 f.write_str("FOR ");
4445 f.write_node(value);
4446 }
4447 WithOptionValue::Refresh(opt) => f.write_node(opt),
4448 WithOptionValue::ClusterScheduleOptionValue(value) => f.write_node(value),
4449 WithOptionValue::ClusterAlterStrategy(value) => f.write_node(value),
4450 }
4451 }
4452}
4453impl_display_t!(WithOptionValue);
4454
4455#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4456pub enum RefreshOptionValue<T: AstInfo> {
4457 OnCommit,
4458 AtCreation,
4459 At(RefreshAtOptionValue<T>),
4460 Every(RefreshEveryOptionValue<T>),
4461}
4462
4463#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4464pub struct RefreshAtOptionValue<T: AstInfo> {
4465 pub time: Expr<T>,
4467}
4468
4469#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4470pub struct RefreshEveryOptionValue<T: AstInfo> {
4471 pub interval: IntervalValue,
4473 pub aligned_to: Option<Expr<T>>,
4475}
4476
4477impl<T: AstInfo> AstDisplay for RefreshOptionValue<T> {
4478 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4479 match self {
4480 RefreshOptionValue::OnCommit => {
4481 f.write_str("ON COMMIT");
4482 }
4483 RefreshOptionValue::AtCreation => {
4484 f.write_str("AT CREATION");
4485 }
4486 RefreshOptionValue::At(RefreshAtOptionValue { time }) => {
4487 f.write_str("AT ");
4488 f.write_node(time);
4489 }
4490 RefreshOptionValue::Every(RefreshEveryOptionValue {
4491 interval,
4492 aligned_to,
4493 }) => {
4494 f.write_str("EVERY '");
4495 f.write_node(interval);
4496 if let Some(aligned_to) = aligned_to {
4497 f.write_str(" ALIGNED TO ");
4498 f.write_node(aligned_to)
4499 }
4500 }
4501 }
4502 }
4503}
4504
4505#[derive(
4506 Debug,
4507 Clone,
4508 PartialEq,
4509 Eq,
4510 Hash,
4511 PartialOrd,
4512 Ord,
4513 Deserialize,
4514 Serialize
4515)]
4516pub enum ClusterScheduleOptionValue {
4517 Manual,
4518 Refresh {
4519 hydration_time_estimate: Option<IntervalValue>,
4520 },
4521}
4522
4523impl Default for ClusterScheduleOptionValue {
4524 fn default() -> Self {
4525 ClusterScheduleOptionValue::Manual
4527 }
4528}
4529
4530impl AstDisplay for ClusterScheduleOptionValue {
4531 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4532 match self {
4533 ClusterScheduleOptionValue::Manual => {
4534 f.write_str("MANUAL");
4535 }
4536 ClusterScheduleOptionValue::Refresh {
4537 hydration_time_estimate,
4538 } => {
4539 f.write_str("ON REFRESH");
4540 if let Some(hydration_time_estimate) = hydration_time_estimate {
4541 f.write_str(" (HYDRATION TIME ESTIMATE = '");
4542 f.write_node(hydration_time_estimate);
4543 f.write_str(")");
4544 }
4545 }
4546 }
4547 }
4548}
4549
4550#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4551pub enum TransactionMode {
4552 AccessMode(TransactionAccessMode),
4553 IsolationLevel(TransactionIsolationLevel),
4554}
4555
4556impl AstDisplay for TransactionMode {
4557 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4558 use TransactionMode::*;
4559 match self {
4560 AccessMode(access_mode) => f.write_node(access_mode),
4561 IsolationLevel(iso_level) => {
4562 f.write_str("ISOLATION LEVEL ");
4563 f.write_node(iso_level);
4564 }
4565 }
4566 }
4567}
4568impl_display!(TransactionMode);
4569
4570#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4571pub enum TransactionAccessMode {
4572 ReadOnly,
4573 ReadWrite,
4574}
4575
4576impl AstDisplay for TransactionAccessMode {
4577 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4578 use TransactionAccessMode::*;
4579 f.write_str(match self {
4580 ReadOnly => "READ ONLY",
4581 ReadWrite => "READ WRITE",
4582 })
4583 }
4584}
4585impl_display!(TransactionAccessMode);
4586
4587#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
4588pub enum TransactionIsolationLevel {
4589 ReadUncommitted,
4590 ReadCommitted,
4591 RepeatableRead,
4592 Serializable,
4593 StrongSessionSerializable,
4594 StrictSerializable,
4595}
4596
4597impl AstDisplay for TransactionIsolationLevel {
4598 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4599 use TransactionIsolationLevel::*;
4600 f.write_str(match self {
4601 ReadUncommitted => "READ UNCOMMITTED",
4602 ReadCommitted => "READ COMMITTED",
4603 RepeatableRead => "REPEATABLE READ",
4604 Serializable => "SERIALIZABLE",
4605 StrongSessionSerializable => "STRONG SESSION SERIALIZABLE",
4606 StrictSerializable => "STRICT SERIALIZABLE",
4607 })
4608 }
4609}
4610impl_display!(TransactionIsolationLevel);
4611
4612#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4613pub enum SetVariableTo {
4614 Default,
4615 Values(Vec<SetVariableValue>),
4616}
4617
4618impl AstDisplay for SetVariableTo {
4619 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4620 use SetVariableTo::*;
4621 match self {
4622 Values(values) => f.write_node(&display::comma_separated(values)),
4623 Default => f.write_str("DEFAULT"),
4624 }
4625 }
4626}
4627impl_display!(SetVariableTo);
4628
4629#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4630pub enum SetVariableValue {
4631 Ident(Ident),
4632 Literal(Value),
4633}
4634
4635impl AstDisplay for SetVariableValue {
4636 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4637 use SetVariableValue::*;
4638 match self {
4639 Ident(ident) => f.write_node(ident),
4640 Literal(literal) => f.write_node(literal),
4641 }
4642 }
4643}
4644impl_display!(SetVariableValue);
4645
4646impl SetVariableValue {
4647 pub fn into_unquoted_value(self) -> String {
4649 match self {
4650 SetVariableValue::Literal(Value::String(s)) => s,
4653 SetVariableValue::Literal(lit) => lit.to_string(),
4654 SetVariableValue::Ident(ident) => ident.into_string(),
4655 }
4656 }
4657}
4658
4659#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4661pub struct Assignment<T: AstInfo> {
4662 pub id: Ident,
4663 pub value: Expr<T>,
4664}
4665
4666impl<T: AstInfo> AstDisplay for Assignment<T> {
4667 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4668 f.write_node(&self.id);
4669 f.write_str(" = ");
4670 f.write_node(&self.value);
4671 }
4672}
4673impl_display_t!(Assignment);
4674
4675#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4677pub enum ExplainStage {
4678 RawPlan,
4680 DecorrelatedPlan,
4682 LocalPlan,
4684 GlobalPlan,
4686 PhysicalPlan,
4688 Trace,
4690 PlanInsights,
4692}
4693
4694impl ExplainStage {
4695 pub fn paths(&self) -> Option<SmallVec<[NamedPlan; 4]>> {
4697 use NamedPlan::*;
4698 match self {
4699 Self::RawPlan => Some(smallvec![Raw]),
4700 Self::DecorrelatedPlan => Some(smallvec![Decorrelated]),
4701 Self::LocalPlan => Some(smallvec![Local]),
4702 Self::GlobalPlan => Some(smallvec![Global]),
4703 Self::PhysicalPlan => Some(smallvec![Physical]),
4704 Self::Trace => None,
4705 Self::PlanInsights => Some(smallvec![Raw, Global, FastPath]),
4706 }
4707 }
4708
4709 pub fn show_fast_path(&self) -> bool {
4712 match self {
4713 Self::RawPlan => false,
4714 Self::DecorrelatedPlan => false,
4715 Self::LocalPlan => false,
4716 Self::GlobalPlan => true,
4717 Self::PhysicalPlan => true,
4718 Self::Trace => false,
4719 Self::PlanInsights => false,
4720 }
4721 }
4722}
4723
4724impl AstDisplay for ExplainStage {
4725 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4726 match self {
4727 Self::RawPlan => f.write_str("RAW PLAN"),
4728 Self::DecorrelatedPlan => f.write_str("DECORRELATED PLAN"),
4729 Self::LocalPlan => f.write_str("LOCALLY OPTIMIZED PLAN"),
4730 Self::GlobalPlan => f.write_str("OPTIMIZED PLAN"),
4731 Self::PhysicalPlan => f.write_str("PHYSICAL PLAN"),
4732 Self::Trace => f.write_str("OPTIMIZER TRACE"),
4733 Self::PlanInsights => f.write_str("PLAN INSIGHTS"),
4734 }
4735 }
4736}
4737impl_display!(ExplainStage);
4738
4739#[derive(Clone)]
4742pub enum NamedPlan {
4743 Raw,
4744 Decorrelated,
4745 Local,
4746 Global,
4747 Physical,
4748 FastPath,
4749}
4750
4751impl NamedPlan {
4752 pub fn of_path(value: &str) -> Option<Self> {
4754 match value {
4755 "optimize/raw" => Some(Self::Raw),
4756 "optimize/hir_to_mir" => Some(Self::Decorrelated),
4757 "optimize/local" => Some(Self::Local),
4758 "optimize/global" => Some(Self::Global),
4759 "optimize/finalize_dataflow" => Some(Self::Physical),
4760 "optimize/fast_path" => Some(Self::FastPath),
4761 _ => None,
4762 }
4763 }
4764
4765 pub fn path(&self) -> &'static str {
4768 match self {
4769 Self::Raw => "optimize/raw",
4770 Self::Decorrelated => "optimize/hir_to_mir",
4771 Self::Local => "optimize/local",
4772 Self::Global => "optimize/global",
4773 Self::Physical => "optimize/finalize_dataflow",
4774 Self::FastPath => "optimize/fast_path",
4775 }
4776 }
4777}
4778
4779#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4782pub enum Explainee<T: AstInfo> {
4783 View(T::ItemName),
4784 MaterializedView(T::ItemName),
4785 Index(T::ItemName),
4786 ReplanView(T::ItemName),
4787 ReplanMaterializedView(T::ItemName),
4788 ReplanIndex(T::ItemName),
4789 Select(Box<SelectStatement<T>>, bool),
4790 CreateView(Box<CreateViewStatement<T>>, bool),
4791 CreateMaterializedView(Box<CreateMaterializedViewStatement<T>>, bool),
4792 CreateIndex(Box<CreateIndexStatement<T>>, bool),
4793 Subscribe(Box<SubscribeStatement<T>>, bool),
4794}
4795
4796impl<T: AstInfo> Explainee<T> {
4797 pub fn name(&self) -> Option<&T::ItemName> {
4798 match self {
4799 Self::View(name)
4800 | Self::ReplanView(name)
4801 | Self::MaterializedView(name)
4802 | Self::ReplanMaterializedView(name)
4803 | Self::Index(name)
4804 | Self::ReplanIndex(name) => Some(name),
4805 Self::Select(..)
4806 | Self::CreateView(..)
4807 | Self::CreateMaterializedView(..)
4808 | Self::CreateIndex(..)
4809 | Self::Subscribe(..) => None,
4810 }
4811 }
4812
4813 pub fn is_view(&self) -> bool {
4814 use Explainee::*;
4815 matches!(self, View(_) | ReplanView(_) | CreateView(_, _))
4816 }
4817}
4818
4819impl<T: AstInfo> AstDisplay for Explainee<T> {
4820 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4821 match self {
4822 Self::View(name) => {
4823 f.write_str("VIEW ");
4824 f.write_node(name);
4825 }
4826 Self::MaterializedView(name) => {
4827 f.write_str("MATERIALIZED VIEW ");
4828 f.write_node(name);
4829 }
4830 Self::Index(name) => {
4831 f.write_str("INDEX ");
4832 f.write_node(name);
4833 }
4834 Self::ReplanView(name) => {
4835 f.write_str("REPLAN VIEW ");
4836 f.write_node(name);
4837 }
4838 Self::ReplanMaterializedView(name) => {
4839 f.write_str("REPLAN MATERIALIZED VIEW ");
4840 f.write_node(name);
4841 }
4842 Self::ReplanIndex(name) => {
4843 f.write_str("REPLAN INDEX ");
4844 f.write_node(name);
4845 }
4846 Self::Select(select, broken) => {
4847 if *broken {
4848 f.write_str("BROKEN ");
4849 }
4850 f.write_node(select);
4851 }
4852 Self::CreateView(statement, broken) => {
4853 if *broken {
4854 f.write_str("BROKEN ");
4855 }
4856 f.write_node(statement);
4857 }
4858 Self::CreateMaterializedView(statement, broken) => {
4859 if *broken {
4860 f.write_str("BROKEN ");
4861 }
4862 f.write_node(statement);
4863 }
4864 Self::CreateIndex(statement, broken) => {
4865 if *broken {
4866 f.write_str("BROKEN ");
4867 }
4868 f.write_node(statement);
4869 }
4870 Self::Subscribe(statement, broken) => {
4871 if *broken {
4872 f.write_str("BROKEN ");
4873 }
4874 f.write_node(statement);
4875 }
4876 }
4877 }
4878}
4879impl_display_t!(Explainee);
4880
4881#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4882pub enum ExplainFormat {
4883 Text,
4885 VerboseText,
4887 Json,
4889 Dot,
4891}
4892
4893impl AstDisplay for ExplainFormat {
4894 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4895 match self {
4896 Self::Text => f.write_str("TEXT"),
4897 Self::VerboseText => f.write_str("VERBOSE TEXT"),
4898 Self::Json => f.write_str("JSON"),
4899 Self::Dot => f.write_str("DOT"),
4900 }
4901 }
4902}
4903impl_display!(ExplainFormat);
4904
4905#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4906pub enum IfExistsBehavior {
4907 Error,
4908 Skip,
4909 Replace,
4910}
4911
4912#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4914pub struct DeclareStatement<T: AstInfo> {
4915 pub name: Ident,
4916 pub stmt: Box<T::NestedStatement>,
4917 pub sql: String,
4918}
4919
4920impl<T: AstInfo> AstDisplay for DeclareStatement<T> {
4921 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4922 f.write_str("DECLARE ");
4923 f.write_node(&self.name);
4924 f.write_str(" CURSOR FOR ");
4925 f.write_node(&self.stmt);
4926 }
4927}
4928impl_display_t!(DeclareStatement);
4929
4930#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4932pub struct CloseStatement {
4933 pub name: Ident,
4934}
4935
4936impl AstDisplay for CloseStatement {
4937 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4938 f.write_str("CLOSE ");
4939 f.write_node(&self.name);
4940 }
4941}
4942impl_display!(CloseStatement);
4943
4944#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4945pub enum FetchOptionName {
4946 Timeout,
4947}
4948
4949impl AstDisplay for FetchOptionName {
4950 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4951 f.write_str(match self {
4952 FetchOptionName::Timeout => "TIMEOUT",
4953 })
4954 }
4955}
4956
4957impl WithOptionName for FetchOptionName {
4958 fn redact_value(&self) -> bool {
4964 match self {
4965 FetchOptionName::Timeout => false,
4966 }
4967 }
4968}
4969
4970#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4971pub struct FetchOption<T: AstInfo> {
4972 pub name: FetchOptionName,
4973 pub value: Option<WithOptionValue<T>>,
4974}
4975impl_display_for_with_option!(FetchOption);
4976
4977#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4979pub struct FetchStatement<T: AstInfo> {
4980 pub name: Ident,
4981 pub count: Option<FetchDirection>,
4982 pub options: Vec<FetchOption<T>>,
4983}
4984
4985impl<T: AstInfo> AstDisplay for FetchStatement<T> {
4986 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4987 f.write_str("FETCH ");
4988 if let Some(ref count) = self.count {
4989 f.write_str(format!("{} ", count));
4990 }
4991 f.write_node(&self.name);
4992 if !self.options.is_empty() {
4993 f.write_str(" WITH (");
4994 f.write_node(&display::comma_separated(&self.options));
4995 f.write_str(")");
4996 }
4997 }
4998}
4999impl_display_t!(FetchStatement);
5000
5001#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5002pub enum FetchDirection {
5003 ForwardAll,
5004 ForwardCount(u64),
5005}
5006
5007impl AstDisplay for FetchDirection {
5008 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5009 match self {
5010 FetchDirection::ForwardAll => f.write_str("ALL"),
5011 FetchDirection::ForwardCount(count) => f.write_str(format!("{}", count)),
5012 }
5013 }
5014}
5015impl_display!(FetchDirection);
5016
5017#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5019pub struct PrepareStatement<T: AstInfo> {
5020 pub name: Ident,
5021 pub stmt: Box<T::NestedStatement>,
5022 pub sql: String,
5023}
5024
5025impl<T: AstInfo> AstDisplay for PrepareStatement<T> {
5026 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5027 f.write_str("PREPARE ");
5028 f.write_node(&self.name);
5029 f.write_str(" AS ");
5030 f.write_node(&self.stmt);
5031 }
5032}
5033impl_display_t!(PrepareStatement);
5034
5035#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5037pub struct ExecuteStatement<T: AstInfo> {
5038 pub name: Ident,
5039 pub params: Vec<Expr<T>>,
5040}
5041
5042impl<T: AstInfo> AstDisplay for ExecuteStatement<T> {
5043 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5044 f.write_str("EXECUTE ");
5045 f.write_node(&self.name);
5046 if !self.params.is_empty() {
5047 f.write_str(" (");
5048 f.write_node(&display::comma_separated(&self.params));
5049 f.write_str(")");
5050 }
5051 }
5052}
5053impl_display_t!(ExecuteStatement);
5054
5055#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5057pub struct ExecuteUnitTestStatement<T: AstInfo> {
5058 pub name: Ident,
5059 pub target: T::ItemName,
5060 pub at_time: Option<Expr<T>>,
5061 pub mocks: Vec<MockViewDef<T>>,
5062 pub expected: ExpectedResultDef<T>,
5063}
5064
5065impl<T: AstInfo> AstDisplay for ExecuteUnitTestStatement<T> {
5066 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5067 f.write_str("EXECUTE UNIT TEST ");
5068 f.write_node(&self.name);
5069 f.write_str(" FOR ");
5070 f.write_node(&self.target);
5071 if let Some(at_time) = &self.at_time {
5072 f.write_str(" AT TIME ");
5073 f.write_node(at_time);
5074 }
5075 for (i, mock) in self.mocks.iter().enumerate() {
5076 f.write_str(if i == 0 { " MOCK " } else { ", MOCK " });
5077 f.write_node(mock);
5078 }
5079 f.write_str(" EXPECTED ");
5080 f.write_node(&self.expected);
5081 }
5082}
5083impl_display_t!(ExecuteUnitTestStatement);
5084
5085#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5087pub struct MockViewDef<T: AstInfo> {
5088 pub name: T::ItemName,
5089 pub columns: Vec<ColumnDef<T>>,
5090 pub query: Query<T>,
5091}
5092
5093impl<T: AstInfo> AstDisplay for MockViewDef<T> {
5094 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5095 f.write_node(&self.name);
5096 f.write_str("(");
5097 f.write_node(&display::comma_separated(&self.columns));
5098 f.write_str(") AS (");
5099 f.write_node(&self.query);
5100 f.write_str(")");
5101 }
5102}
5103impl_display_t!(MockViewDef);
5104
5105#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5107pub struct ExpectedResultDef<T: AstInfo> {
5108 pub columns: Vec<ColumnDef<T>>,
5109 pub query: Query<T>,
5110}
5111
5112impl<T: AstInfo> AstDisplay for ExpectedResultDef<T> {
5113 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5114 f.write_str("(");
5115 f.write_node(&display::comma_separated(&self.columns));
5116 f.write_str(") AS (");
5117 f.write_node(&self.query);
5118 f.write_str(")");
5119 }
5120}
5121impl_display_t!(ExpectedResultDef);
5122
5123#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5125pub struct DeallocateStatement {
5126 pub name: Option<Ident>,
5127}
5128
5129impl AstDisplay for DeallocateStatement {
5130 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5131 f.write_str("DEALLOCATE ");
5132 match &self.name {
5133 Some(name) => f.write_node(name),
5134 None => f.write_str("ALL"),
5135 };
5136 }
5137}
5138impl_display!(DeallocateStatement);
5139
5140#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5142pub struct RaiseStatement {
5143 pub severity: NoticeSeverity,
5144}
5145
5146impl AstDisplay for RaiseStatement {
5147 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5148 f.write_str("RAISE ");
5149 f.write_node(&self.severity);
5150 }
5151}
5152impl_display!(RaiseStatement);
5153
5154#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5155pub enum NoticeSeverity {
5156 Debug,
5157 Info,
5158 Log,
5159 Notice,
5160 Warning,
5161}
5162
5163impl AstDisplay for NoticeSeverity {
5164 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5165 f.write_str(match self {
5166 NoticeSeverity::Debug => "DEBUG",
5167 NoticeSeverity::Info => "INFO",
5168 NoticeSeverity::Log => "LOG",
5169 NoticeSeverity::Notice => "NOTICE",
5170 NoticeSeverity::Warning => "WARNING",
5171 })
5172 }
5173}
5174impl_display!(NoticeSeverity);
5175
5176#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5178pub struct AlterSystemSetStatement {
5179 pub name: Ident,
5180 pub to: SetVariableTo,
5181}
5182
5183impl AstDisplay for AlterSystemSetStatement {
5184 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5185 f.write_str("ALTER SYSTEM SET ");
5186 f.write_node(&self.name);
5187 f.write_str(" = ");
5188 f.write_node(&self.to);
5189 }
5190}
5191impl_display!(AlterSystemSetStatement);
5192
5193#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5195pub struct AlterSystemResetStatement {
5196 pub name: Ident,
5197}
5198
5199impl AstDisplay for AlterSystemResetStatement {
5200 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5201 f.write_str("ALTER SYSTEM RESET ");
5202 f.write_node(&self.name);
5203 }
5204}
5205impl_display!(AlterSystemResetStatement);
5206
5207#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5209pub struct AlterSystemResetAllStatement {}
5210
5211impl AstDisplay for AlterSystemResetAllStatement {
5212 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5213 f.write_str("ALTER SYSTEM RESET ALL");
5214 }
5215}
5216impl_display!(AlterSystemResetAllStatement);
5217
5218#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5219pub enum AsOf<T: AstInfo> {
5220 At(Expr<T>),
5221 AtLeast(Expr<T>),
5222}
5223
5224impl<T: AstInfo> AstDisplay for AsOf<T> {
5225 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5226 f.write_str("AS OF ");
5227 match self {
5228 AsOf::At(expr) => f.write_node(expr),
5229 AsOf::AtLeast(expr) => {
5230 f.write_str("AT LEAST ");
5231 f.write_node(expr);
5232 }
5233 }
5234 }
5235}
5236impl_display_t!(AsOf);
5237
5238#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
5239pub enum ShowStatement<T: AstInfo> {
5240 ShowObjects(ShowObjectsStatement<T>),
5241 ShowColumns(ShowColumnsStatement<T>),
5242 ShowCreateView(ShowCreateViewStatement<T>),
5243 ShowCreateMaterializedView(ShowCreateMaterializedViewStatement<T>),
5244 ShowCreateSource(ShowCreateSourceStatement<T>),
5245 ShowCreateTable(ShowCreateTableStatement<T>),
5246 ShowCreateSink(ShowCreateSinkStatement<T>),
5247 ShowCreateIndex(ShowCreateIndexStatement<T>),
5248 ShowCreateConnection(ShowCreateConnectionStatement<T>),
5249 ShowCreateCluster(ShowCreateClusterStatement<T>),
5250 ShowCreateType(ShowCreateTypeStatement<T>),
5251 ShowVariable(ShowVariableStatement),
5252 InspectShard(InspectShardStatement),
5253}
5254
5255impl<T: AstInfo> AstDisplay for ShowStatement<T> {
5256 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5257 match self {
5258 ShowStatement::ShowObjects(stmt) => f.write_node(stmt),
5259 ShowStatement::ShowColumns(stmt) => f.write_node(stmt),
5260 ShowStatement::ShowCreateView(stmt) => f.write_node(stmt),
5261 ShowStatement::ShowCreateMaterializedView(stmt) => f.write_node(stmt),
5262 ShowStatement::ShowCreateSource(stmt) => f.write_node(stmt),
5263 ShowStatement::ShowCreateTable(stmt) => f.write_node(stmt),
5264 ShowStatement::ShowCreateSink(stmt) => f.write_node(stmt),
5265 ShowStatement::ShowCreateIndex(stmt) => f.write_node(stmt),
5266 ShowStatement::ShowCreateConnection(stmt) => f.write_node(stmt),
5267 ShowStatement::ShowCreateCluster(stmt) => f.write_node(stmt),
5268 ShowStatement::ShowCreateType(stmt) => f.write_node(stmt),
5269 ShowStatement::ShowVariable(stmt) => f.write_node(stmt),
5270 ShowStatement::InspectShard(stmt) => f.write_node(stmt),
5271 }
5272 }
5273}
5274impl_display_t!(ShowStatement);
5275
5276#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5278pub struct GrantRoleStatement<T: AstInfo> {
5279 pub role_names: Vec<T::RoleName>,
5281 pub member_names: Vec<T::RoleName>,
5283}
5284
5285impl<T: AstInfo> AstDisplay for GrantRoleStatement<T> {
5286 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5287 f.write_str("GRANT ");
5288 f.write_node(&display::comma_separated(&self.role_names));
5289 f.write_str(" TO ");
5290 f.write_node(&display::comma_separated(&self.member_names));
5291 }
5292}
5293impl_display_t!(GrantRoleStatement);
5294
5295#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5297pub struct RevokeRoleStatement<T: AstInfo> {
5298 pub role_names: Vec<T::RoleName>,
5300 pub member_names: Vec<T::RoleName>,
5302}
5303
5304impl<T: AstInfo> AstDisplay for RevokeRoleStatement<T> {
5305 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5306 f.write_str("REVOKE ");
5307 f.write_node(&display::comma_separated(&self.role_names));
5308 f.write_str(" FROM ");
5309 f.write_node(&display::comma_separated(&self.member_names));
5310 }
5311}
5312impl_display_t!(RevokeRoleStatement);
5313
5314#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5315pub enum Privilege {
5316 SELECT,
5317 INSERT,
5318 UPDATE,
5319 DELETE,
5320 USAGE,
5321 CREATE,
5322 CREATEROLE,
5323 CREATEDB,
5324 CREATECLUSTER,
5325 CREATENETWORKPOLICY,
5326}
5327
5328impl AstDisplay for Privilege {
5329 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5330 f.write_str(match self {
5331 Privilege::SELECT => "SELECT",
5332 Privilege::INSERT => "INSERT",
5333 Privilege::UPDATE => "UPDATE",
5334 Privilege::DELETE => "DELETE",
5335 Privilege::CREATE => "CREATE",
5336 Privilege::USAGE => "USAGE",
5337 Privilege::CREATEROLE => "CREATEROLE",
5338 Privilege::CREATEDB => "CREATEDB",
5339 Privilege::CREATECLUSTER => "CREATECLUSTER",
5340 Privilege::CREATENETWORKPOLICY => "CREATENETWORKPOLICY",
5341 });
5342 }
5343}
5344impl_display!(Privilege);
5345
5346#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5347pub enum PrivilegeSpecification {
5348 All,
5349 Privileges(Vec<Privilege>),
5350}
5351
5352impl AstDisplay for PrivilegeSpecification {
5353 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5354 match self {
5355 PrivilegeSpecification::All => f.write_str("ALL"),
5356 PrivilegeSpecification::Privileges(privileges) => {
5357 f.write_node(&display::comma_separated(privileges))
5358 }
5359 }
5360 }
5361}
5362impl_display!(PrivilegeSpecification);
5363
5364#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5365pub enum GrantTargetSpecification<T: AstInfo> {
5366 Object {
5367 object_type: ObjectType,
5371 object_spec_inner: GrantTargetSpecificationInner<T>,
5373 },
5374 System,
5375}
5376
5377#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5378pub enum GrantTargetSpecificationInner<T: AstInfo> {
5379 All(GrantTargetAllSpecification<T>),
5380 Objects { names: Vec<T::ObjectName> },
5381}
5382
5383#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5384pub enum GrantTargetAllSpecification<T: AstInfo> {
5385 All,
5386 AllDatabases { databases: Vec<T::DatabaseName> },
5387 AllSchemas { schemas: Vec<T::SchemaName> },
5388}
5389
5390impl<T: AstInfo> GrantTargetAllSpecification<T> {
5391 pub fn len(&self) -> usize {
5392 match self {
5393 GrantTargetAllSpecification::All => 1,
5394 GrantTargetAllSpecification::AllDatabases { databases } => databases.len(),
5395 GrantTargetAllSpecification::AllSchemas { schemas } => schemas.len(),
5396 }
5397 }
5398}
5399
5400impl<T: AstInfo> AstDisplay for GrantTargetSpecification<T> {
5401 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5402 match self {
5403 GrantTargetSpecification::Object {
5404 object_type,
5405 object_spec_inner,
5406 } => match object_spec_inner {
5407 GrantTargetSpecificationInner::All(all_spec) => match all_spec {
5408 GrantTargetAllSpecification::All => {
5409 f.write_str("ALL ");
5410 f.write_node(object_type);
5411 f.write_str("S");
5412 }
5413 GrantTargetAllSpecification::AllDatabases { databases } => {
5414 f.write_str("ALL ");
5415 f.write_node(object_type);
5416 f.write_str("S IN DATABASE ");
5417 f.write_node(&display::comma_separated(databases));
5418 }
5419 GrantTargetAllSpecification::AllSchemas { schemas } => {
5420 f.write_str("ALL ");
5421 f.write_node(object_type);
5422 f.write_str("S IN SCHEMA ");
5423 f.write_node(&display::comma_separated(schemas));
5424 }
5425 },
5426 GrantTargetSpecificationInner::Objects { names } => {
5427 f.write_node(object_type);
5428 f.write_str(" ");
5429 f.write_node(&display::comma_separated(names));
5430 }
5431 },
5432 GrantTargetSpecification::System => f.write_str("SYSTEM"),
5433 }
5434 }
5435}
5436impl_display_t!(GrantTargetSpecification);
5437
5438#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5440pub struct GrantPrivilegesStatement<T: AstInfo> {
5441 pub privileges: PrivilegeSpecification,
5443 pub target: GrantTargetSpecification<T>,
5445 pub roles: Vec<T::RoleName>,
5447}
5448
5449impl<T: AstInfo> AstDisplay for GrantPrivilegesStatement<T> {
5450 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5451 f.write_str("GRANT ");
5452 f.write_node(&self.privileges);
5453 f.write_str(" ON ");
5454 f.write_node(&self.target);
5455 f.write_str(" TO ");
5456 f.write_node(&display::comma_separated(&self.roles));
5457 }
5458}
5459impl_display_t!(GrantPrivilegesStatement);
5460
5461#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5463pub struct RevokePrivilegesStatement<T: AstInfo> {
5464 pub privileges: PrivilegeSpecification,
5466 pub target: GrantTargetSpecification<T>,
5468 pub roles: Vec<T::RoleName>,
5470}
5471
5472impl<T: AstInfo> AstDisplay for RevokePrivilegesStatement<T> {
5473 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5474 f.write_str("REVOKE ");
5475 f.write_node(&self.privileges);
5476 f.write_str(" ON ");
5477 f.write_node(&self.target);
5478 f.write_str(" FROM ");
5479 f.write_node(&display::comma_separated(&self.roles));
5480 }
5481}
5482impl_display_t!(RevokePrivilegesStatement);
5483
5484#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5485pub enum TargetRoleSpecification<T: AstInfo> {
5486 Roles(Vec<T::RoleName>),
5488 AllRoles,
5490}
5491
5492impl<T: AstInfo> AstDisplay for TargetRoleSpecification<T> {
5493 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5494 match self {
5495 TargetRoleSpecification::Roles(roles) => f.write_node(&display::comma_separated(roles)),
5496 TargetRoleSpecification::AllRoles => f.write_str("ALL ROLES"),
5497 }
5498 }
5499}
5500impl_display_t!(TargetRoleSpecification);
5501
5502#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5503pub struct AbbreviatedGrantStatement<T: AstInfo> {
5504 pub privileges: PrivilegeSpecification,
5506 pub object_type: ObjectType,
5510 pub grantees: Vec<T::RoleName>,
5512}
5513
5514impl<T: AstInfo> AstDisplay for AbbreviatedGrantStatement<T> {
5515 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5516 f.write_str("GRANT ");
5517 f.write_node(&self.privileges);
5518 f.write_str(" ON ");
5519 f.write_node(&self.object_type);
5520 f.write_str("S TO ");
5521 f.write_node(&display::comma_separated(&self.grantees));
5522 }
5523}
5524impl_display_t!(AbbreviatedGrantStatement);
5525
5526#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5527pub struct AbbreviatedRevokeStatement<T: AstInfo> {
5528 pub privileges: PrivilegeSpecification,
5530 pub object_type: ObjectType,
5534 pub revokees: Vec<T::RoleName>,
5536}
5537
5538impl<T: AstInfo> AstDisplay for AbbreviatedRevokeStatement<T> {
5539 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5540 f.write_str("REVOKE ");
5541 f.write_node(&self.privileges);
5542 f.write_str(" ON ");
5543 f.write_node(&self.object_type);
5544 f.write_str("S FROM ");
5545 f.write_node(&display::comma_separated(&self.revokees));
5546 }
5547}
5548impl_display_t!(AbbreviatedRevokeStatement);
5549
5550#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5551pub enum AbbreviatedGrantOrRevokeStatement<T: AstInfo> {
5552 Grant(AbbreviatedGrantStatement<T>),
5553 Revoke(AbbreviatedRevokeStatement<T>),
5554}
5555
5556impl<T: AstInfo> AbbreviatedGrantOrRevokeStatement<T> {
5557 pub fn privileges(&self) -> &PrivilegeSpecification {
5558 match self {
5559 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.privileges,
5560 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.privileges,
5561 }
5562 }
5563
5564 pub fn object_type(&self) -> &ObjectType {
5565 match self {
5566 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.object_type,
5567 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.object_type,
5568 }
5569 }
5570
5571 pub fn roles(&self) -> &Vec<T::RoleName> {
5572 match self {
5573 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.grantees,
5574 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.revokees,
5575 }
5576 }
5577}
5578
5579impl<T: AstInfo> AstDisplay for AbbreviatedGrantOrRevokeStatement<T> {
5580 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5581 match self {
5582 AbbreviatedGrantOrRevokeStatement::Grant(grant) => f.write_node(grant),
5583 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => f.write_node(revoke),
5584 }
5585 }
5586}
5587impl_display_t!(AbbreviatedGrantOrRevokeStatement);
5588
5589#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5591pub struct AlterDefaultPrivilegesStatement<T: AstInfo> {
5592 pub target_roles: TargetRoleSpecification<T>,
5594 pub target_objects: GrantTargetAllSpecification<T>,
5596 pub grant_or_revoke: AbbreviatedGrantOrRevokeStatement<T>,
5598}
5599
5600impl<T: AstInfo> AstDisplay for AlterDefaultPrivilegesStatement<T> {
5601 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5602 f.write_str("ALTER DEFAULT PRIVILEGES");
5603 match &self.target_roles {
5604 TargetRoleSpecification::Roles(_) => {
5605 f.write_str(" FOR ROLE ");
5606 f.write_node(&self.target_roles);
5607 }
5608 TargetRoleSpecification::AllRoles => {
5609 f.write_str(" FOR ");
5610 f.write_node(&self.target_roles);
5611 }
5612 }
5613 match &self.target_objects {
5614 GrantTargetAllSpecification::All => {}
5615 GrantTargetAllSpecification::AllDatabases { databases } => {
5616 f.write_str(" IN DATABASE ");
5617 f.write_node(&display::comma_separated(databases));
5618 }
5619 GrantTargetAllSpecification::AllSchemas { schemas } => {
5620 f.write_str(" IN SCHEMA ");
5621 f.write_node(&display::comma_separated(schemas));
5622 }
5623 }
5624 f.write_str(" ");
5625 f.write_node(&self.grant_or_revoke);
5626 }
5627}
5628impl_display_t!(AlterDefaultPrivilegesStatement);
5629
5630#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5632pub struct ReassignOwnedStatement<T: AstInfo> {
5633 pub old_roles: Vec<T::RoleName>,
5635 pub new_role: T::RoleName,
5637}
5638
5639impl<T: AstInfo> AstDisplay for ReassignOwnedStatement<T> {
5640 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5641 f.write_str("REASSIGN OWNED BY ");
5642 f.write_node(&display::comma_separated(&self.old_roles));
5643 f.write_str(" TO ");
5644 f.write_node(&self.new_role);
5645 }
5646}
5647impl_display_t!(ReassignOwnedStatement);
5648
5649#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5651pub struct CommentStatement<T: AstInfo> {
5652 pub object: CommentObjectType<T>,
5653 pub comment: Option<String>,
5654}
5655
5656impl<T: AstInfo> AstDisplay for CommentStatement<T> {
5657 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5658 f.write_str("COMMENT ON ");
5659 f.write_node(&self.object);
5660
5661 f.write_str(" IS ");
5662 match &self.comment {
5663 Some(s) => {
5664 f.write_str("'");
5665 f.write_node(&display::escape_single_quote_string(s));
5666 f.write_str("'");
5667 }
5668 None => f.write_str("NULL"),
5669 }
5670 }
5671}
5672impl_display_t!(CommentStatement);
5673
5674#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
5675pub struct ColumnName<T: AstInfo> {
5676 pub relation: T::ItemName,
5677 pub column: T::ColumnReference,
5678}
5679
5680impl<T: AstInfo> AstDisplay for ColumnName<T> {
5681 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5682 f.write_node(&self.relation);
5683 f.write_str(".");
5684 f.write_node(&self.column);
5685 }
5686}
5687impl_display_t!(ColumnName);
5688
5689#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5690pub enum CommentObjectType<T: AstInfo> {
5691 Table { name: T::ItemName },
5692 View { name: T::ItemName },
5693 Column { name: ColumnName<T> },
5694 MaterializedView { name: T::ItemName },
5695 Source { name: T::ItemName },
5696 Sink { name: T::ItemName },
5697 Index { name: T::ItemName },
5698 Func { name: T::ItemName },
5699 Connection { name: T::ItemName },
5700 Type { ty: T::DataType },
5701 Secret { name: T::ItemName },
5702 Role { name: T::RoleName },
5703 Database { name: T::DatabaseName },
5704 Schema { name: T::SchemaName },
5705 Cluster { name: T::ClusterName },
5706 ClusterReplica { name: QualifiedReplica },
5707 NetworkPolicy { name: T::NetworkPolicyName },
5708}
5709
5710impl<T: AstInfo> AstDisplay for CommentObjectType<T> {
5711 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5712 use CommentObjectType::*;
5713
5714 match self {
5715 Table { name } => {
5716 f.write_str("TABLE ");
5717 f.write_node(name);
5718 }
5719 View { name } => {
5720 f.write_str("VIEW ");
5721 f.write_node(name);
5722 }
5723 Column { name } => {
5724 f.write_str("COLUMN ");
5725 f.write_node(name);
5726 }
5727 MaterializedView { name } => {
5728 f.write_str("MATERIALIZED VIEW ");
5729 f.write_node(name);
5730 }
5731 Source { name } => {
5732 f.write_str("SOURCE ");
5733 f.write_node(name);
5734 }
5735 Sink { name } => {
5736 f.write_str("SINK ");
5737 f.write_node(name);
5738 }
5739 Index { name } => {
5740 f.write_str("INDEX ");
5741 f.write_node(name);
5742 }
5743 Func { name } => {
5744 f.write_str("FUNCTION ");
5745 f.write_node(name);
5746 }
5747 Connection { name } => {
5748 f.write_str("CONNECTION ");
5749 f.write_node(name);
5750 }
5751 Type { ty } => {
5752 f.write_str("TYPE ");
5753 f.write_node(ty);
5754 }
5755 Secret { name } => {
5756 f.write_str("SECRET ");
5757 f.write_node(name);
5758 }
5759 Role { name } => {
5760 f.write_str("ROLE ");
5761 f.write_node(name);
5762 }
5763 Database { name } => {
5764 f.write_str("DATABASE ");
5765 f.write_node(name);
5766 }
5767 Schema { name } => {
5768 f.write_str("SCHEMA ");
5769 f.write_node(name);
5770 }
5771 Cluster { name } => {
5772 f.write_str("CLUSTER ");
5773 f.write_node(name);
5774 }
5775 ClusterReplica { name } => {
5776 f.write_str("CLUSTER REPLICA ");
5777 f.write_node(name);
5778 }
5779 NetworkPolicy { name } => {
5780 f.write_str("NETWORK POLICY ");
5781 f.write_node(name);
5782 }
5783 }
5784 }
5785}
5786
5787impl_display_t!(CommentObjectType);
5788
5789include!(concat!(env!("OUT_DIR"), "/display.simple_options.rs"));