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