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