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