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