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