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 AutoScalingStrategy,
2252 AvailabilityZones,
2254 Disk,
2256 ExperimentalArrangementCompression,
2258 IntrospectionInterval,
2260 IntrospectionDebugging,
2262 Managed,
2264 Replicas,
2266 ReplicationFactor,
2268 Size,
2270 Schedule,
2272 WorkloadClass,
2274}
2275
2276impl AstDisplay for ClusterOptionName {
2277 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2278 match self {
2279 ClusterOptionName::AutoScalingStrategy => f.write_str("AUTO SCALING STRATEGY"),
2280 ClusterOptionName::AvailabilityZones => f.write_str("AVAILABILITY ZONES"),
2281 ClusterOptionName::Disk => f.write_str("DISK"),
2282 ClusterOptionName::ExperimentalArrangementCompression => {
2283 f.write_str("EXPERIMENTAL ARRANGEMENT COMPRESSION")
2284 }
2285 ClusterOptionName::IntrospectionDebugging => f.write_str("INTROSPECTION DEBUGGING"),
2286 ClusterOptionName::IntrospectionInterval => f.write_str("INTROSPECTION INTERVAL"),
2287 ClusterOptionName::Managed => f.write_str("MANAGED"),
2288 ClusterOptionName::Replicas => f.write_str("REPLICAS"),
2289 ClusterOptionName::ReplicationFactor => f.write_str("REPLICATION FACTOR"),
2290 ClusterOptionName::Size => f.write_str("SIZE"),
2291 ClusterOptionName::Schedule => f.write_str("SCHEDULE"),
2292 ClusterOptionName::WorkloadClass => f.write_str("WORKLOAD CLASS"),
2293 }
2294 }
2295}
2296
2297impl WithOptionName for ClusterOptionName {
2298 fn redact_value(&self) -> bool {
2304 match self {
2305 ClusterOptionName::AutoScalingStrategy
2306 | ClusterOptionName::AvailabilityZones
2307 | ClusterOptionName::Disk
2308 | ClusterOptionName::ExperimentalArrangementCompression
2309 | ClusterOptionName::IntrospectionDebugging
2310 | ClusterOptionName::IntrospectionInterval
2311 | ClusterOptionName::Managed
2312 | ClusterOptionName::Replicas
2313 | ClusterOptionName::ReplicationFactor
2314 | ClusterOptionName::Size
2315 | ClusterOptionName::Schedule
2316 | ClusterOptionName::WorkloadClass => false,
2317 }
2318 }
2319}
2320
2321#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2322pub struct ClusterOption<T: AstInfo> {
2324 pub name: ClusterOptionName,
2325 pub value: Option<WithOptionValue<T>>,
2326}
2327impl_display_for_with_option!(ClusterOption);
2328
2329#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2330pub enum ClusterAlterUntilReadyOptionName {
2331 Timeout,
2332 OnTimeout,
2333}
2334
2335impl AstDisplay for ClusterAlterUntilReadyOptionName {
2336 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2337 match self {
2338 Self::Timeout => f.write_str("TIMEOUT"),
2339 Self::OnTimeout => f.write_str("ON TIMEOUT"),
2340 }
2341 }
2342}
2343
2344impl WithOptionName for ClusterAlterUntilReadyOptionName {
2345 fn redact_value(&self) -> bool {
2351 match self {
2352 ClusterAlterUntilReadyOptionName::Timeout
2353 | ClusterAlterUntilReadyOptionName::OnTimeout => false,
2354 }
2355 }
2356}
2357
2358#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2359pub struct ClusterAlterUntilReadyOption<T: AstInfo> {
2360 pub name: ClusterAlterUntilReadyOptionName,
2361 pub value: Option<WithOptionValue<T>>,
2362}
2363impl_display_for_with_option!(ClusterAlterUntilReadyOption);
2364
2365#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2366pub enum ClusterAlterOptionName {
2367 Wait,
2368}
2369
2370impl AstDisplay for ClusterAlterOptionName {
2371 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2372 match self {
2373 ClusterAlterOptionName::Wait => f.write_str("WAIT"),
2374 }
2375 }
2376}
2377
2378impl WithOptionName for ClusterAlterOptionName {
2379 fn redact_value(&self) -> bool {
2385 match self {
2386 ClusterAlterOptionName::Wait => false,
2387 }
2388 }
2389}
2390
2391#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2392pub enum ClusterAlterOptionValue<T: AstInfo> {
2393 For(Value),
2394 UntilReady(Vec<ClusterAlterUntilReadyOption<T>>),
2395}
2396
2397impl<T: AstInfo> AstDisplay for ClusterAlterOptionValue<T> {
2398 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2399 match self {
2400 ClusterAlterOptionValue::For(duration) => {
2401 f.write_str("FOR ");
2402 f.write_node(duration);
2403 }
2404 ClusterAlterOptionValue::UntilReady(options) => {
2405 f.write_str("UNTIL READY (");
2406 f.write_node(&display::comma_separated(options));
2407 f.write_str(")");
2408 }
2409 }
2410 }
2411}
2412
2413#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2414pub struct ClusterAlterOption<T: AstInfo> {
2416 pub name: ClusterAlterOptionName,
2417 pub value: Option<WithOptionValue<T>>,
2418}
2419
2420impl_display_for_with_option!(ClusterAlterOption);
2421
2422#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2425pub enum ClusterFeatureName {
2426 ReoptimizeImportedViews,
2427 EnableNewOuterJoinLowering,
2428 EnableEagerDeltaJoins,
2429 EnableVariadicLeftJoinLowering,
2430 EnableLetrecFixpointAnalysis,
2431 EnableJoinPrioritizeArranged,
2432 EnableProjectionPushdownAfterRelationCse,
2433}
2434
2435impl WithOptionName for ClusterFeatureName {
2436 fn redact_value(&self) -> bool {
2442 match self {
2443 Self::ReoptimizeImportedViews
2444 | Self::EnableNewOuterJoinLowering
2445 | Self::EnableEagerDeltaJoins
2446 | Self::EnableVariadicLeftJoinLowering
2447 | Self::EnableLetrecFixpointAnalysis
2448 | Self::EnableJoinPrioritizeArranged
2449 | Self::EnableProjectionPushdownAfterRelationCse => false,
2450 }
2451 }
2452}
2453
2454#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2455pub struct ClusterFeature<T: AstInfo> {
2456 pub name: ClusterFeatureName,
2457 pub value: Option<WithOptionValue<T>>,
2458}
2459impl_display_for_with_option!(ClusterFeature);
2460
2461#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2463pub struct CreateClusterStatement<T: AstInfo> {
2464 pub name: Ident,
2466 pub options: Vec<ClusterOption<T>>,
2468 pub features: Vec<ClusterFeature<T>>,
2470}
2471
2472impl<T: AstInfo> AstDisplay for CreateClusterStatement<T> {
2473 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2474 f.write_str("CREATE CLUSTER ");
2475 f.write_node(&self.name);
2476 if !self.options.is_empty() {
2477 f.write_str(" (");
2478 f.write_node(&display::comma_separated(&self.options));
2479 f.write_str(")");
2480 }
2481 if !self.features.is_empty() {
2482 f.write_str(" FEATURES (");
2483 f.write_node(&display::comma_separated(&self.features));
2484 f.write_str(")");
2485 }
2486 }
2487}
2488impl_display_t!(CreateClusterStatement);
2489
2490#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2491pub struct ReplicaDefinition<T: AstInfo> {
2492 pub name: Ident,
2494 pub options: Vec<ReplicaOption<T>>,
2496}
2497
2498impl<T: AstInfo> AstDisplay for ReplicaDefinition<T> {
2501 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2502 f.write_node(&self.name);
2503 f.write_str(" (");
2504 f.write_node(&display::comma_separated(&self.options));
2505 f.write_str(")");
2506 }
2507}
2508impl_display_t!(ReplicaDefinition);
2509
2510#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2511pub enum AlterClusterAction<T: AstInfo> {
2512 SetOptions {
2513 options: Vec<ClusterOption<T>>,
2514 with_options: Vec<ClusterAlterOption<T>>,
2515 },
2516 ResetOptions(Vec<ClusterOptionName>),
2517}
2518
2519#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2521pub struct AlterClusterStatement<T: AstInfo> {
2522 pub if_exists: bool,
2524 pub name: Ident,
2526 pub action: AlterClusterAction<T>,
2528}
2529
2530impl<T: AstInfo> AstDisplay for AlterClusterStatement<T> {
2531 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2532 f.write_str("ALTER CLUSTER ");
2533 if self.if_exists {
2534 f.write_str("IF EXISTS ");
2535 }
2536 f.write_node(&self.name);
2537 f.write_str(" ");
2538 match &self.action {
2539 AlterClusterAction::SetOptions {
2540 options,
2541 with_options,
2542 } => {
2543 f.write_str("SET (");
2544 f.write_node(&display::comma_separated(options));
2545 f.write_str(")");
2546 if !with_options.is_empty() {
2547 f.write_str(" WITH (");
2548 f.write_node(&display::comma_separated(with_options));
2549 f.write_str(")");
2550 }
2551 }
2552 AlterClusterAction::ResetOptions(options) => {
2553 f.write_str("RESET (");
2554 f.write_node(&display::comma_separated(options));
2555 f.write_str(")");
2556 }
2557 }
2558 }
2559}
2560impl_display_t!(AlterClusterStatement);
2561
2562#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2564pub struct CreateClusterReplicaStatement<T: AstInfo> {
2565 pub of_cluster: Ident,
2567 pub definition: ReplicaDefinition<T>,
2569}
2570
2571impl<T: AstInfo> AstDisplay for CreateClusterReplicaStatement<T> {
2572 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2573 f.write_str("CREATE CLUSTER REPLICA ");
2574 f.write_node(&self.of_cluster);
2575 f.write_str(".");
2576 f.write_node(&self.definition.name);
2577 f.write_str(" (");
2578 f.write_node(&display::comma_separated(&self.definition.options));
2579 f.write_str(")");
2580 }
2581}
2582impl_display_t!(CreateClusterReplicaStatement);
2583
2584#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2585pub enum ReplicaOptionName {
2586 BilledAs,
2588 Size,
2590 AvailabilityZone,
2592 StorageAddresses,
2594 StoragectlAddresses,
2596 ComputectlAddresses,
2598 ComputeAddresses,
2600 Workers,
2602 Internal,
2604 IntrospectionInterval,
2606 IntrospectionDebugging,
2608 Disk,
2610 ExperimentalArrangementCompression,
2612}
2613
2614impl AstDisplay for ReplicaOptionName {
2615 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2616 match self {
2617 ReplicaOptionName::BilledAs => f.write_str("BILLED AS"),
2618 ReplicaOptionName::Size => f.write_str("SIZE"),
2619 ReplicaOptionName::AvailabilityZone => f.write_str("AVAILABILITY ZONE"),
2620 ReplicaOptionName::StorageAddresses => f.write_str("STORAGE ADDRESSES"),
2621 ReplicaOptionName::StoragectlAddresses => f.write_str("STORAGECTL ADDRESSES"),
2622 ReplicaOptionName::ComputectlAddresses => f.write_str("COMPUTECTL ADDRESSES"),
2623 ReplicaOptionName::ComputeAddresses => f.write_str("COMPUTE ADDRESSES"),
2624 ReplicaOptionName::Workers => f.write_str("WORKERS"),
2625 ReplicaOptionName::Internal => f.write_str("INTERNAL"),
2626 ReplicaOptionName::IntrospectionInterval => f.write_str("INTROSPECTION INTERVAL"),
2627 ReplicaOptionName::IntrospectionDebugging => f.write_str("INTROSPECTION DEBUGGING"),
2628 ReplicaOptionName::Disk => f.write_str("DISK"),
2629 ReplicaOptionName::ExperimentalArrangementCompression => {
2630 f.write_str("EXPERIMENTAL ARRANGEMENT COMPRESSION")
2631 }
2632 }
2633 }
2634}
2635
2636impl WithOptionName for ReplicaOptionName {
2637 fn redact_value(&self) -> bool {
2643 match self {
2644 ReplicaOptionName::BilledAs
2645 | ReplicaOptionName::Size
2646 | ReplicaOptionName::AvailabilityZone
2647 | ReplicaOptionName::StorageAddresses
2648 | ReplicaOptionName::StoragectlAddresses
2649 | ReplicaOptionName::ComputectlAddresses
2650 | ReplicaOptionName::ComputeAddresses
2651 | ReplicaOptionName::Workers
2652 | ReplicaOptionName::Internal
2653 | ReplicaOptionName::IntrospectionInterval
2654 | ReplicaOptionName::IntrospectionDebugging
2655 | ReplicaOptionName::Disk
2656 | ReplicaOptionName::ExperimentalArrangementCompression => false,
2657 }
2658 }
2659}
2660
2661#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2662pub struct ReplicaOption<T: AstInfo> {
2664 pub name: ReplicaOptionName,
2665 pub value: Option<WithOptionValue<T>>,
2666}
2667impl_display_for_with_option!(ReplicaOption);
2668
2669#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2671pub enum CreateTypeAs<T: AstInfo> {
2672 List {
2673 options: Vec<CreateTypeListOption<T>>,
2674 },
2675 Map {
2676 options: Vec<CreateTypeMapOption<T>>,
2677 },
2678 Record {
2679 column_defs: Vec<ColumnDef<T>>,
2680 },
2681}
2682
2683impl<T: AstInfo> AstDisplay for CreateTypeAs<T> {
2684 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2685 match self {
2686 CreateTypeAs::List { .. } => f.write_str("LIST "),
2687 CreateTypeAs::Map { .. } => f.write_str("MAP "),
2688 CreateTypeAs::Record { .. } => f.write_str("RECORD "),
2689 }
2690 }
2691}
2692impl_display_t!(CreateTypeAs);
2693
2694#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2695pub enum CreateTypeListOptionName {
2696 ElementType,
2697}
2698
2699impl AstDisplay for CreateTypeListOptionName {
2700 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2701 f.write_str(match self {
2702 CreateTypeListOptionName::ElementType => "ELEMENT TYPE",
2703 })
2704 }
2705}
2706
2707impl WithOptionName for CreateTypeListOptionName {
2708 fn redact_value(&self) -> bool {
2714 match self {
2715 CreateTypeListOptionName::ElementType => false,
2716 }
2717 }
2718}
2719
2720#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2721pub struct CreateTypeListOption<T: AstInfo> {
2722 pub name: CreateTypeListOptionName,
2723 pub value: Option<WithOptionValue<T>>,
2724}
2725impl_display_for_with_option!(CreateTypeListOption);
2726
2727#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2728pub enum CreateTypeMapOptionName {
2729 KeyType,
2730 ValueType,
2731}
2732
2733impl AstDisplay for CreateTypeMapOptionName {
2734 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2735 f.write_str(match self {
2736 CreateTypeMapOptionName::KeyType => "KEY TYPE",
2737 CreateTypeMapOptionName::ValueType => "VALUE TYPE",
2738 })
2739 }
2740}
2741
2742impl WithOptionName for CreateTypeMapOptionName {
2743 fn redact_value(&self) -> bool {
2749 match self {
2750 CreateTypeMapOptionName::KeyType | CreateTypeMapOptionName::ValueType => false,
2751 }
2752 }
2753}
2754
2755#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2756pub struct CreateTypeMapOption<T: AstInfo> {
2757 pub name: CreateTypeMapOptionName,
2758 pub value: Option<WithOptionValue<T>>,
2759}
2760impl_display_for_with_option!(CreateTypeMapOption);
2761
2762#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2764pub struct AlterOwnerStatement<T: AstInfo> {
2765 pub object_type: ObjectType,
2766 pub if_exists: bool,
2767 pub name: UnresolvedObjectName,
2768 pub new_owner: T::RoleName,
2769}
2770
2771impl<T: AstInfo> AstDisplay for AlterOwnerStatement<T> {
2772 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2773 f.write_str("ALTER ");
2774 f.write_node(&self.object_type);
2775 f.write_str(" ");
2776 if self.if_exists {
2777 f.write_str("IF EXISTS ");
2778 }
2779 f.write_node(&self.name);
2780 f.write_str(" OWNER TO ");
2781 f.write_node(&self.new_owner);
2782 }
2783}
2784impl_display_t!(AlterOwnerStatement);
2785
2786#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2788pub struct AlterObjectRenameStatement {
2789 pub object_type: ObjectType,
2790 pub if_exists: bool,
2791 pub name: UnresolvedObjectName,
2792 pub to_item_name: Ident,
2793}
2794
2795impl AstDisplay for AlterObjectRenameStatement {
2796 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2797 f.write_str("ALTER ");
2798 f.write_node(&self.object_type);
2799 f.write_str(" ");
2800 if self.if_exists {
2801 f.write_str("IF EXISTS ");
2802 }
2803 f.write_node(&self.name);
2804 f.write_str(" RENAME TO ");
2805 f.write_node(&self.to_item_name);
2806 }
2807}
2808impl_display!(AlterObjectRenameStatement);
2809
2810#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2812pub struct AlterRetainHistoryStatement<T: AstInfo> {
2813 pub object_type: ObjectType,
2814 pub if_exists: bool,
2815 pub name: UnresolvedObjectName,
2816 pub history: Option<WithOptionValue<T>>,
2817}
2818
2819impl<T: AstInfo> AstDisplay for AlterRetainHistoryStatement<T> {
2820 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2821 f.write_str("ALTER ");
2822 f.write_node(&self.object_type);
2823 f.write_str(" ");
2824 if self.if_exists {
2825 f.write_str("IF EXISTS ");
2826 }
2827 f.write_node(&self.name);
2828 if let Some(history) = &self.history {
2829 f.write_str(" SET (RETAIN HISTORY ");
2830 f.write_node(history);
2831 } else {
2832 f.write_str(" RESET (RETAIN HISTORY");
2833 }
2834 f.write_str(")");
2835 }
2836}
2837impl_display_t!(AlterRetainHistoryStatement);
2838
2839#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2841pub struct AlterObjectSwapStatement {
2842 pub object_type: ObjectType,
2843 pub if_exists: bool,
2844 pub name_a: UnresolvedObjectName,
2845 pub name_b: Ident,
2846}
2847
2848impl AstDisplay for AlterObjectSwapStatement {
2849 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2850 f.write_str("ALTER ");
2851
2852 f.write_node(&self.object_type);
2853 f.write_str(" ");
2854 if self.if_exists {
2855 f.write_str("IF EXISTS ");
2856 }
2857 f.write_node(&self.name_a);
2858
2859 f.write_str(" SWAP WITH ");
2860 f.write_node(&self.name_b);
2861 }
2862}
2863impl_display!(AlterObjectSwapStatement);
2864
2865#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2866pub enum AlterIndexAction<T: AstInfo> {
2867 SetOptions(Vec<IndexOption<T>>),
2868 ResetOptions(Vec<IndexOptionName>),
2869}
2870
2871#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2873pub struct AlterIndexStatement<T: AstInfo> {
2874 pub index_name: UnresolvedItemName,
2875 pub if_exists: bool,
2876 pub action: AlterIndexAction<T>,
2877}
2878
2879impl<T: AstInfo> AstDisplay for AlterIndexStatement<T> {
2880 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2881 f.write_str("ALTER INDEX ");
2882 if self.if_exists {
2883 f.write_str("IF EXISTS ");
2884 }
2885 f.write_node(&self.index_name);
2886 f.write_str(" ");
2887
2888 match &self.action {
2889 AlterIndexAction::SetOptions(options) => {
2890 f.write_str("SET (");
2891 f.write_node(&display::comma_separated(options));
2892 f.write_str(")");
2893 }
2894 AlterIndexAction::ResetOptions(options) => {
2895 f.write_str("RESET (");
2896 f.write_node(&display::comma_separated(options));
2897 f.write_str(")");
2898 }
2899 }
2900 }
2901}
2902
2903impl_display_t!(AlterIndexStatement);
2904
2905#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2906pub enum AlterSinkAction<T: AstInfo> {
2907 SetOptions(Vec<CreateSinkOption<T>>),
2908 ResetOptions(Vec<CreateSinkOptionName>),
2909 ChangeRelation(T::ItemName),
2910}
2911
2912#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2913pub struct AlterSinkStatement<T: AstInfo> {
2914 pub sink_name: UnresolvedItemName,
2915 pub if_exists: bool,
2916 pub action: AlterSinkAction<T>,
2917}
2918
2919impl<T: AstInfo> AstDisplay for AlterSinkStatement<T> {
2920 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2921 f.write_str("ALTER SINK ");
2922 if self.if_exists {
2923 f.write_str("IF EXISTS ");
2924 }
2925 f.write_node(&self.sink_name);
2926 f.write_str(" ");
2927
2928 match &self.action {
2929 AlterSinkAction::ChangeRelation(from) => {
2930 f.write_str("SET FROM ");
2931 f.write_node(from);
2932 }
2933 AlterSinkAction::SetOptions(options) => {
2934 f.write_str("SET (");
2935 f.write_node(&display::comma_separated(options));
2936 f.write_str(")");
2937 }
2938 AlterSinkAction::ResetOptions(options) => {
2939 f.write_str("RESET (");
2940 f.write_node(&display::comma_separated(options));
2941 f.write_str(")");
2942 }
2943 }
2944 }
2945}
2946
2947#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2948pub enum AlterSourceAddSubsourceOptionName {
2949 TextColumns,
2951 ExcludeColumns,
2953 Details,
2958}
2959
2960impl AstDisplay for AlterSourceAddSubsourceOptionName {
2961 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
2962 f.write_str(match self {
2963 AlterSourceAddSubsourceOptionName::TextColumns => "TEXT COLUMNS",
2964 AlterSourceAddSubsourceOptionName::ExcludeColumns => "EXCLUDE COLUMNS",
2965 AlterSourceAddSubsourceOptionName::Details => "DETAILS",
2966 })
2967 }
2968}
2969impl_display!(AlterSourceAddSubsourceOptionName);
2970
2971impl WithOptionName for AlterSourceAddSubsourceOptionName {
2972 fn redact_value(&self) -> bool {
2978 match self {
2979 AlterSourceAddSubsourceOptionName::Details
2980 | AlterSourceAddSubsourceOptionName::TextColumns
2981 | AlterSourceAddSubsourceOptionName::ExcludeColumns => false,
2982 }
2983 }
2984}
2985
2986#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2987pub struct AlterSourceAddSubsourceOption<T: AstInfo> {
2989 pub name: AlterSourceAddSubsourceOptionName,
2990 pub value: Option<WithOptionValue<T>>,
2991}
2992impl_display_for_with_option!(AlterSourceAddSubsourceOption);
2993impl_display_t!(AlterSourceAddSubsourceOption);
2994
2995#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2996pub enum AlterSourceAction<T: AstInfo> {
2997 SetOptions(Vec<CreateSourceOption<T>>),
2998 ResetOptions(Vec<CreateSourceOptionName>),
2999 AddSubsources {
3000 external_references: Vec<ExternalReferenceExport>,
3001 options: Vec<AlterSourceAddSubsourceOption<T>>,
3002 },
3003 DropSubsources {
3004 if_exists: bool,
3005 cascade: bool,
3006 names: Vec<UnresolvedItemName>,
3007 },
3008 RefreshReferences,
3009}
3010
3011impl<T: AstInfo> AstDisplay for AlterSourceAction<T> {
3012 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3013 where
3014 W: fmt::Write,
3015 {
3016 match &self {
3017 AlterSourceAction::SetOptions(options) => {
3018 f.write_str("SET (");
3019 f.write_node(&display::comma_separated(options));
3020 f.write_str(")");
3021 }
3022 AlterSourceAction::ResetOptions(options) => {
3023 f.write_str("RESET (");
3024 f.write_node(&display::comma_separated(options));
3025 f.write_str(")");
3026 }
3027 AlterSourceAction::DropSubsources {
3028 if_exists,
3029 cascade,
3030 names,
3031 } => {
3032 f.write_str("DROP SUBSOURCE ");
3033 if *if_exists {
3034 f.write_str("IF EXISTS ");
3035 }
3036
3037 f.write_node(&display::comma_separated(names));
3038
3039 if *cascade {
3040 f.write_str(" CASCADE");
3041 }
3042 }
3043 AlterSourceAction::AddSubsources {
3044 external_references: subsources,
3045 options,
3046 } => {
3047 f.write_str("ADD SUBSOURCE ");
3048
3049 f.write_node(&display::comma_separated(subsources));
3050
3051 if !options.is_empty() {
3052 f.write_str(" WITH (");
3053 f.write_node(&display::comma_separated(options));
3054 f.write_str(")");
3055 }
3056 }
3057 AlterSourceAction::RefreshReferences => {
3058 f.write_str("REFRESH REFERENCES");
3059 }
3060 }
3061 }
3062}
3063
3064#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3065pub struct AlterSourceStatement<T: AstInfo> {
3066 pub source_name: UnresolvedItemName,
3067 pub if_exists: bool,
3068 pub action: AlterSourceAction<T>,
3069}
3070
3071impl<T: AstInfo> AstDisplay for AlterSourceStatement<T> {
3072 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3073 f.write_str("ALTER SOURCE ");
3074 if self.if_exists {
3075 f.write_str("IF EXISTS ");
3076 }
3077 f.write_node(&self.source_name);
3078 f.write_str(" ");
3079 f.write_node(&self.action)
3080 }
3081}
3082
3083impl_display_t!(AlterSourceStatement);
3084
3085#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3087pub struct AlterSecretStatement<T: AstInfo> {
3088 pub name: UnresolvedItemName,
3089 pub if_exists: bool,
3090 pub value: Expr<T>,
3091}
3092
3093impl<T: AstInfo> AstDisplay for AlterSecretStatement<T> {
3094 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3095 f.write_str("ALTER SECRET ");
3096 if self.if_exists {
3097 f.write_str("IF EXISTS ");
3098 }
3099 f.write_node(&self.name);
3100 f.write_str(" AS ");
3101
3102 if f.redacted() {
3103 f.write_str("'<REDACTED>'");
3104 } else {
3105 f.write_node(&self.value);
3106 }
3107 }
3108}
3109
3110impl_display_t!(AlterSecretStatement);
3111
3112#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3113pub enum AlterConnectionAction<T: AstInfo> {
3114 RotateKeys,
3115 SetOption(ConnectionOption<T>),
3116 DropOption(ConnectionOptionName),
3117}
3118
3119impl<T: AstInfo> AstDisplay for AlterConnectionAction<T> {
3120 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3121 match self {
3122 AlterConnectionAction::RotateKeys => f.write_str("ROTATE KEYS"),
3123 AlterConnectionAction::SetOption(option) => {
3124 f.write_str("SET (");
3125 f.write_node(option);
3126 f.write_str(")");
3127 }
3128 AlterConnectionAction::DropOption(option) => {
3129 f.write_str("DROP (");
3130 f.write_node(option);
3131 f.write_str(")");
3132 }
3133 }
3134 }
3135}
3136impl_display_t!(AlterConnectionAction);
3137
3138#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3139pub enum AlterConnectionOptionName {
3140 Validate,
3141}
3142
3143impl AstDisplay for AlterConnectionOptionName {
3144 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3145 f.write_str(match self {
3146 AlterConnectionOptionName::Validate => "VALIDATE",
3147 })
3148 }
3149}
3150impl_display!(AlterConnectionOptionName);
3151
3152impl WithOptionName for AlterConnectionOptionName {
3153 fn redact_value(&self) -> bool {
3159 match self {
3160 AlterConnectionOptionName::Validate => false,
3161 }
3162 }
3163}
3164
3165#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3166pub struct AlterConnectionOption<T: AstInfo> {
3168 pub name: AlterConnectionOptionName,
3169 pub value: Option<WithOptionValue<T>>,
3170}
3171impl_display_for_with_option!(AlterConnectionOption);
3172impl_display_t!(AlterConnectionOption);
3173
3174#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3176pub struct AlterConnectionStatement<T: AstInfo> {
3177 pub name: UnresolvedItemName,
3178 pub if_exists: bool,
3179 pub actions: Vec<AlterConnectionAction<T>>,
3180 pub with_options: Vec<AlterConnectionOption<T>>,
3181}
3182
3183impl<T: AstInfo> AstDisplay for AlterConnectionStatement<T> {
3184 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3185 f.write_str("ALTER CONNECTION ");
3186 if self.if_exists {
3187 f.write_str("IF EXISTS ");
3188 }
3189 f.write_node(&self.name);
3190 f.write_str(" ");
3191 f.write_node(&display::comma_separated(&self.actions));
3192
3193 if !self.with_options.is_empty() {
3194 f.write_str(" WITH (");
3195 f.write_node(&display::comma_separated(&self.with_options));
3196 f.write_str(")");
3197 }
3198 }
3199}
3200
3201impl_display_t!(AlterConnectionStatement);
3202
3203#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3205pub struct AlterRoleStatement<T: AstInfo> {
3206 pub name: T::RoleName,
3208 pub option: AlterRoleOption,
3210}
3211
3212impl<T: AstInfo> AstDisplay for AlterRoleStatement<T> {
3213 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3214 f.write_str("ALTER ROLE ");
3215 f.write_node(&self.name);
3216 f.write_node(&self.option);
3217 }
3218}
3219impl_display_t!(AlterRoleStatement);
3220
3221#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3223pub enum AlterRoleOption {
3224 Attributes(Vec<RoleAttribute>),
3226 Variable(SetRoleVar),
3228}
3229
3230impl AstDisplay for AlterRoleOption {
3231 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3232 match self {
3233 AlterRoleOption::Attributes(attrs) => {
3234 for attr in attrs {
3235 f.write_str(" ");
3236 attr.fmt(f)
3237 }
3238 }
3239 AlterRoleOption::Variable(var) => {
3240 f.write_str(" ");
3241 f.write_node(var);
3242 }
3243 }
3244 }
3245}
3246impl_display!(AlterRoleOption);
3247
3248#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3250pub struct AlterTableAddColumnStatement<T: AstInfo> {
3251 pub if_exists: bool,
3252 pub name: UnresolvedItemName,
3253 pub if_col_not_exist: bool,
3254 pub column_name: Ident,
3255 pub data_type: T::DataType,
3256}
3257
3258impl<T: AstInfo> AstDisplay for AlterTableAddColumnStatement<T> {
3259 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3260 where
3261 W: fmt::Write,
3262 {
3263 f.write_str("ALTER TABLE ");
3264 if self.if_exists {
3265 f.write_str("IF EXISTS ");
3266 }
3267 f.write_node(&self.name);
3268
3269 f.write_str(" ADD COLUMN ");
3270 if self.if_col_not_exist {
3271 f.write_str("IF NOT EXISTS ");
3272 }
3273
3274 f.write_node(&self.column_name);
3275 f.write_str(" ");
3276 f.write_node(&self.data_type);
3277 }
3278}
3279
3280impl_display_t!(AlterTableAddColumnStatement);
3281
3282#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3284pub struct AlterMaterializedViewApplyReplacementStatement {
3285 pub if_exists: bool,
3286 pub name: UnresolvedItemName,
3287 pub replacement_name: UnresolvedItemName,
3288}
3289
3290impl AstDisplay for AlterMaterializedViewApplyReplacementStatement {
3291 fn fmt<W>(&self, f: &mut AstFormatter<W>)
3292 where
3293 W: fmt::Write,
3294 {
3295 f.write_str("ALTER MATERIALIZED VIEW ");
3296 if self.if_exists {
3297 f.write_str("IF EXISTS ");
3298 }
3299 f.write_node(&self.name);
3300
3301 f.write_str(" APPLY REPLACEMENT ");
3302 f.write_node(&self.replacement_name);
3303 }
3304}
3305
3306impl_display!(AlterMaterializedViewApplyReplacementStatement);
3307
3308#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3309pub struct DiscardStatement {
3310 pub target: DiscardTarget,
3311}
3312
3313impl AstDisplay for DiscardStatement {
3314 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3315 f.write_str("DISCARD ");
3316 f.write_node(&self.target);
3317 }
3318}
3319impl_display!(DiscardStatement);
3320
3321#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3322pub enum DiscardTarget {
3323 Plans,
3324 Sequences,
3325 Temp,
3326 All,
3327}
3328
3329impl AstDisplay for DiscardTarget {
3330 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3331 match self {
3332 DiscardTarget::Plans => f.write_str("PLANS"),
3333 DiscardTarget::Sequences => f.write_str("SEQUENCES"),
3334 DiscardTarget::Temp => f.write_str("TEMP"),
3335 DiscardTarget::All => f.write_str("ALL"),
3336 }
3337 }
3338}
3339impl_display!(DiscardTarget);
3340
3341#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3343pub struct DropObjectsStatement {
3344 pub object_type: ObjectType,
3346 pub if_exists: bool,
3348 pub names: Vec<UnresolvedObjectName>,
3350 pub cascade: bool,
3353}
3354
3355impl AstDisplay for DropObjectsStatement {
3356 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3357 f.write_str("DROP ");
3358 f.write_node(&self.object_type);
3359 f.write_str(" ");
3360 if self.if_exists {
3361 f.write_str("IF EXISTS ");
3362 }
3363 f.write_node(&display::comma_separated(&self.names));
3364 if self.cascade && self.object_type != ObjectType::Database {
3365 f.write_str(" CASCADE");
3366 } else if !self.cascade && self.object_type == ObjectType::Database {
3367 f.write_str(" RESTRICT");
3368 }
3369 }
3370}
3371impl_display!(DropObjectsStatement);
3372
3373#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3375pub struct DropOwnedStatement<T: AstInfo> {
3376 pub role_names: Vec<T::RoleName>,
3378 pub cascade: Option<bool>,
3381}
3382
3383impl<T: AstInfo> DropOwnedStatement<T> {
3384 pub fn cascade(&self) -> bool {
3385 self.cascade == Some(true)
3386 }
3387}
3388
3389impl<T: AstInfo> AstDisplay for DropOwnedStatement<T> {
3390 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3391 f.write_str("DROP OWNED BY ");
3392 f.write_node(&display::comma_separated(&self.role_names));
3393 if let Some(true) = self.cascade {
3394 f.write_str(" CASCADE");
3395 } else if let Some(false) = self.cascade {
3396 f.write_str(" RESTRICT");
3397 }
3398 }
3399}
3400impl_display_t!(DropOwnedStatement);
3401
3402#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3403pub struct QualifiedReplica {
3404 pub cluster: Ident,
3405 pub replica: Ident,
3406}
3407
3408impl AstDisplay for QualifiedReplica {
3409 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3410 f.write_node(&self.cluster);
3411 f.write_str(".");
3412 f.write_node(&self.replica);
3413 }
3414}
3415impl_display!(QualifiedReplica);
3416
3417#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3423pub struct SetVariableStatement {
3424 pub local: bool,
3425 pub variable: Ident,
3426 pub to: SetVariableTo,
3427}
3428
3429impl AstDisplay for SetVariableStatement {
3430 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3431 f.write_str("SET ");
3432 if self.local {
3433 f.write_str("LOCAL ");
3434 }
3435 f.write_node(&self.variable);
3436 f.write_str(" = ");
3437 f.write_node(&self.to);
3438 }
3439}
3440impl_display!(SetVariableStatement);
3441
3442#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3447pub struct ResetVariableStatement {
3448 pub variable: Ident,
3449}
3450
3451impl AstDisplay for ResetVariableStatement {
3452 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3453 f.write_str("RESET ");
3454 f.write_node(&self.variable);
3455 }
3456}
3457impl_display!(ResetVariableStatement);
3458
3459#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3461pub struct ShowVariableStatement {
3462 pub variable: Ident,
3463}
3464
3465impl AstDisplay for ShowVariableStatement {
3466 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3467 f.write_str("SHOW ");
3468 f.write_node(&self.variable);
3469 }
3470}
3471impl_display!(ShowVariableStatement);
3472
3473#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3475pub struct InspectShardStatement {
3476 pub id: String,
3477}
3478
3479impl AstDisplay for InspectShardStatement {
3480 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3481 f.write_str("INSPECT SHARD ");
3482 f.write_str("'");
3483 f.write_node(&display::escape_single_quote_string(&self.id));
3484 f.write_str("'");
3485 }
3486}
3487impl_display!(InspectShardStatement);
3488
3489#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3490pub enum ShowObjectType<T: AstInfo> {
3491 MaterializedView {
3492 in_cluster: Option<T::ClusterName>,
3493 },
3494 Index {
3495 in_cluster: Option<T::ClusterName>,
3496 on_object: Option<T::ItemName>,
3497 },
3498 Table {
3499 on_source: Option<T::ItemName>,
3500 },
3501 View,
3502 Source {
3503 in_cluster: Option<T::ClusterName>,
3504 },
3505 Sink {
3506 in_cluster: Option<T::ClusterName>,
3507 },
3508 Type,
3509 Role,
3510 Cluster,
3511 ClusterReplica,
3512 Object,
3513 Secret,
3514 Connection,
3515 Database,
3516 Schema {
3517 from: Option<T::DatabaseName>,
3518 },
3519 Subsource {
3520 on_source: Option<T::ItemName>,
3521 },
3522 Privileges {
3523 object_type: Option<SystemObjectType>,
3524 role: Option<T::RoleName>,
3525 },
3526 DefaultPrivileges {
3527 object_type: Option<ObjectType>,
3528 role: Option<T::RoleName>,
3529 },
3530 RoleMembership {
3531 role: Option<T::RoleName>,
3532 },
3533 NetworkPolicy,
3534}
3535#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3544pub struct ShowObjectsStatement<T: AstInfo> {
3545 pub object_type: ShowObjectType<T>,
3546 pub from: Option<T::SchemaName>,
3547 pub filter: Option<ShowStatementFilter<T>>,
3548}
3549
3550impl<T: AstInfo> AstDisplay for ShowObjectsStatement<T> {
3551 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3552 f.write_str("SHOW");
3553 f.write_str(" ");
3554
3555 f.write_str(match &self.object_type {
3556 ShowObjectType::Table { .. } => "TABLES",
3557 ShowObjectType::View => "VIEWS",
3558 ShowObjectType::Source { .. } => "SOURCES",
3559 ShowObjectType::Sink { .. } => "SINKS",
3560 ShowObjectType::Type => "TYPES",
3561 ShowObjectType::Role => "ROLES",
3562 ShowObjectType::Cluster => "CLUSTERS",
3563 ShowObjectType::ClusterReplica => "CLUSTER REPLICAS",
3564 ShowObjectType::Object => "OBJECTS",
3565 ShowObjectType::Secret => "SECRETS",
3566 ShowObjectType::Connection => "CONNECTIONS",
3567 ShowObjectType::MaterializedView { .. } => "MATERIALIZED VIEWS",
3568 ShowObjectType::Index { .. } => "INDEXES",
3569 ShowObjectType::Database => "DATABASES",
3570 ShowObjectType::Schema { .. } => "SCHEMAS",
3571 ShowObjectType::Subsource { .. } => "SUBSOURCES",
3572 ShowObjectType::Privileges { .. } => "PRIVILEGES",
3573 ShowObjectType::DefaultPrivileges { .. } => "DEFAULT PRIVILEGES",
3574 ShowObjectType::RoleMembership { .. } => "ROLE MEMBERSHIP",
3575 ShowObjectType::NetworkPolicy => "NETWORK POLICIES",
3576 });
3577
3578 if let ShowObjectType::Index { on_object, .. } = &self.object_type {
3579 if let Some(on_object) = on_object {
3580 f.write_str(" ON ");
3581 f.write_node(on_object);
3582 }
3583 }
3584
3585 if let ShowObjectType::Schema { from: Some(from) } = &self.object_type {
3586 f.write_str(" FROM ");
3587 f.write_node(from);
3588 }
3589
3590 if let Some(from) = &self.from {
3591 f.write_str(" FROM ");
3592 f.write_node(from);
3593 }
3594
3595 match &self.object_type {
3597 ShowObjectType::MaterializedView { in_cluster }
3598 | ShowObjectType::Index { in_cluster, .. }
3599 | ShowObjectType::Sink { in_cluster }
3600 | ShowObjectType::Source { in_cluster } => {
3601 if let Some(cluster) = in_cluster {
3602 f.write_str(" IN CLUSTER ");
3603 f.write_node(cluster);
3604 }
3605 }
3606 _ => (),
3607 }
3608
3609 if let ShowObjectType::Subsource { on_source } = &self.object_type {
3610 if let Some(on_source) = on_source {
3611 f.write_str(" ON ");
3612 f.write_node(on_source);
3613 }
3614 }
3615
3616 if let ShowObjectType::Table { on_source } = &self.object_type {
3617 if let Some(on_source) = on_source {
3618 f.write_str(" ON ");
3619 f.write_node(on_source);
3620 }
3621 }
3622
3623 if let ShowObjectType::Privileges { object_type, role } = &self.object_type {
3624 if let Some(object_type) = object_type {
3625 f.write_str(" ON ");
3626 f.write_node(object_type);
3627 if let SystemObjectType::Object(_) = object_type {
3628 f.write_str("S");
3629 }
3630 }
3631 if let Some(role) = role {
3632 f.write_str(" FOR ");
3633 f.write_node(role);
3634 }
3635 }
3636
3637 if let ShowObjectType::DefaultPrivileges { object_type, role } = &self.object_type {
3638 if let Some(object_type) = object_type {
3639 f.write_str(" ON ");
3640 f.write_node(object_type);
3641 f.write_str("S");
3642 }
3643 if let Some(role) = role {
3644 f.write_str(" FOR ");
3645 f.write_node(role);
3646 }
3647 }
3648
3649 if let ShowObjectType::RoleMembership {
3650 role: Some(role), ..
3651 } = &self.object_type
3652 {
3653 f.write_str(" FOR ");
3654 f.write_node(role);
3655 }
3656
3657 if let Some(filter) = &self.filter {
3658 f.write_str(" ");
3659 f.write_node(filter);
3660 }
3661 }
3662}
3663impl_display_t!(ShowObjectsStatement);
3664
3665#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3669pub struct ShowColumnsStatement<T: AstInfo> {
3670 pub table_name: T::ItemName,
3671 pub filter: Option<ShowStatementFilter<T>>,
3672}
3673
3674impl<T: AstInfo> AstDisplay for ShowColumnsStatement<T> {
3675 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3676 f.write_str("SHOW ");
3677 f.write_str("COLUMNS FROM ");
3678 f.write_node(&self.table_name);
3679 if let Some(filter) = &self.filter {
3680 f.write_str(" ");
3681 f.write_node(filter);
3682 }
3683 }
3684}
3685impl_display_t!(ShowColumnsStatement);
3686
3687#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3689pub struct ShowCreateViewStatement<T: AstInfo> {
3690 pub view_name: T::ItemName,
3691 pub redacted: bool,
3692}
3693
3694impl<T: AstInfo> AstDisplay for ShowCreateViewStatement<T> {
3695 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3696 f.write_str("SHOW ");
3697 if self.redacted {
3698 f.write_str("REDACTED ");
3699 }
3700 f.write_str("CREATE VIEW ");
3701 f.write_node(&self.view_name);
3702 }
3703}
3704impl_display_t!(ShowCreateViewStatement);
3705
3706#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3708pub struct ShowCreateMaterializedViewStatement<T: AstInfo> {
3709 pub materialized_view_name: T::ItemName,
3710 pub redacted: bool,
3711}
3712
3713impl<T: AstInfo> AstDisplay for ShowCreateMaterializedViewStatement<T> {
3714 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3715 f.write_str("SHOW ");
3716 if self.redacted {
3717 f.write_str("REDACTED ");
3718 }
3719 f.write_str("CREATE MATERIALIZED VIEW ");
3720 f.write_node(&self.materialized_view_name);
3721 }
3722}
3723impl_display_t!(ShowCreateMaterializedViewStatement);
3724
3725#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3727pub struct ShowCreateSourceStatement<T: AstInfo> {
3728 pub source_name: T::ItemName,
3729 pub redacted: bool,
3730}
3731
3732impl<T: AstInfo> AstDisplay for ShowCreateSourceStatement<T> {
3733 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3734 f.write_str("SHOW ");
3735 if self.redacted {
3736 f.write_str("REDACTED ");
3737 }
3738 f.write_str("CREATE SOURCE ");
3739 f.write_node(&self.source_name);
3740 }
3741}
3742impl_display_t!(ShowCreateSourceStatement);
3743
3744#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3746pub struct ShowCreateTableStatement<T: AstInfo> {
3747 pub table_name: T::ItemName,
3748 pub redacted: bool,
3749}
3750
3751impl<T: AstInfo> AstDisplay for ShowCreateTableStatement<T> {
3752 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3753 f.write_str("SHOW ");
3754 if self.redacted {
3755 f.write_str("REDACTED ");
3756 }
3757 f.write_str("CREATE TABLE ");
3758 f.write_node(&self.table_name);
3759 }
3760}
3761impl_display_t!(ShowCreateTableStatement);
3762
3763#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3765pub struct ShowCreateSinkStatement<T: AstInfo> {
3766 pub sink_name: T::ItemName,
3767 pub redacted: bool,
3768}
3769
3770impl<T: AstInfo> AstDisplay for ShowCreateSinkStatement<T> {
3771 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3772 f.write_str("SHOW ");
3773 if self.redacted {
3774 f.write_str("REDACTED ");
3775 }
3776 f.write_str("CREATE SINK ");
3777 f.write_node(&self.sink_name);
3778 }
3779}
3780impl_display_t!(ShowCreateSinkStatement);
3781
3782#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3784pub struct ShowCreateIndexStatement<T: AstInfo> {
3785 pub index_name: T::ItemName,
3786 pub redacted: bool,
3787}
3788
3789impl<T: AstInfo> AstDisplay for ShowCreateIndexStatement<T> {
3790 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3791 f.write_str("SHOW ");
3792 if self.redacted {
3793 f.write_str("REDACTED ");
3794 }
3795 f.write_str("CREATE INDEX ");
3796 f.write_node(&self.index_name);
3797 }
3798}
3799impl_display_t!(ShowCreateIndexStatement);
3800
3801#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3803pub struct ShowCreateConnectionStatement<T: AstInfo> {
3804 pub connection_name: T::ItemName,
3805 pub redacted: bool,
3806}
3807
3808impl<T: AstInfo> AstDisplay for ShowCreateConnectionStatement<T> {
3809 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3810 f.write_str("SHOW ");
3811 if self.redacted {
3812 f.write_str("REDACTED ");
3813 }
3814 f.write_str("CREATE CONNECTION ");
3815 f.write_node(&self.connection_name);
3816 }
3817}
3818
3819#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3820pub struct ShowCreateClusterStatement<T: AstInfo> {
3821 pub cluster_name: T::ClusterName,
3822}
3823
3824impl<T: AstInfo> AstDisplay for ShowCreateClusterStatement<T> {
3825 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3826 f.write_str("SHOW CREATE CLUSTER ");
3827 f.write_node(&self.cluster_name);
3828 }
3829}
3830
3831#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3833pub struct StartTransactionStatement {
3834 pub modes: Vec<TransactionMode>,
3835}
3836
3837impl AstDisplay for StartTransactionStatement {
3838 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3839 f.write_str("START TRANSACTION");
3840 if !self.modes.is_empty() {
3841 f.write_str(" ");
3842 f.write_node(&display::comma_separated(&self.modes));
3843 }
3844 }
3845}
3846impl_display!(StartTransactionStatement);
3847
3848#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3850pub struct ShowCreateTypeStatement<T: AstInfo> {
3851 pub type_name: T::DataType,
3852 pub redacted: bool,
3853}
3854
3855impl<T: AstInfo> AstDisplay for ShowCreateTypeStatement<T> {
3856 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3857 f.write_str("SHOW ");
3858 if self.redacted {
3859 f.write_str("REDACTED ");
3860 }
3861 f.write_str("CREATE TYPE ");
3862 f.write_node(&self.type_name);
3863 }
3864}
3865
3866#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
3868pub struct SetTransactionStatement {
3869 pub local: bool,
3870 pub modes: Vec<TransactionMode>,
3871}
3872
3873impl AstDisplay for SetTransactionStatement {
3874 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3875 f.write_str("SET ");
3876 if !self.local {
3877 f.write_str("SESSION CHARACTERISTICS AS ");
3878 }
3879 f.write_str("TRANSACTION");
3880 if !self.modes.is_empty() {
3881 f.write_str(" ");
3882 f.write_node(&display::comma_separated(&self.modes));
3883 }
3884 }
3885}
3886impl_display!(SetTransactionStatement);
3887
3888#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3890pub struct CommitStatement {
3891 pub chain: bool,
3892}
3893
3894impl AstDisplay for CommitStatement {
3895 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3896 f.write_str("COMMIT");
3897 if self.chain {
3898 f.write_str(" AND CHAIN");
3899 }
3900 }
3901}
3902impl_display!(CommitStatement);
3903
3904#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3906pub struct RollbackStatement {
3907 pub chain: bool,
3908}
3909
3910impl AstDisplay for RollbackStatement {
3911 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3912 f.write_str("ROLLBACK");
3913 if self.chain {
3914 f.write_str(" AND CHAIN");
3915 }
3916 }
3917}
3918impl_display!(RollbackStatement);
3919
3920#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3921pub enum SubscribeOptionName {
3922 Snapshot,
3923 Progress,
3924}
3925
3926impl AstDisplay for SubscribeOptionName {
3927 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3928 match self {
3929 SubscribeOptionName::Snapshot => f.write_str("SNAPSHOT"),
3930 SubscribeOptionName::Progress => f.write_str("PROGRESS"),
3931 }
3932 }
3933}
3934impl_display!(SubscribeOptionName);
3935
3936impl WithOptionName for SubscribeOptionName {
3937 fn redact_value(&self) -> bool {
3943 match self {
3944 SubscribeOptionName::Snapshot | SubscribeOptionName::Progress => false,
3945 }
3946 }
3947}
3948
3949#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3950pub struct SubscribeOption<T: AstInfo> {
3951 pub name: SubscribeOptionName,
3952 pub value: Option<WithOptionValue<T>>,
3953}
3954impl_display_for_with_option!(SubscribeOption);
3955impl_display_t!(SubscribeOption);
3956
3957#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3959pub struct SubscribeStatement<T: AstInfo> {
3960 pub relation: SubscribeRelation<T>,
3961 pub options: Vec<SubscribeOption<T>>,
3962 pub as_of: Option<AsOf<T>>,
3963 pub up_to: Option<Expr<T>>,
3964 pub output: SubscribeOutput<T>,
3965}
3966
3967impl<T: AstInfo> AstDisplay for SubscribeStatement<T> {
3968 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3969 f.write_str("SUBSCRIBE ");
3970 if self.relation.needs_explicit_to(f.simple()) {
3971 f.write_str("TO ");
3976 }
3977 f.write_node(&self.relation);
3978 if !self.options.is_empty() {
3979 f.write_str(" WITH (");
3980 f.write_node(&display::comma_separated(&self.options));
3981 f.write_str(")");
3982 }
3983 if let Some(as_of) = &self.as_of {
3984 f.write_str(" ");
3985 f.write_node(as_of);
3986 }
3987 if let Some(up_to) = &self.up_to {
3988 f.write_str(" UP TO ");
3989 f.write_node(up_to);
3990 }
3991 f.write_str(&self.output);
3992 }
3993}
3994impl_display_t!(SubscribeStatement);
3995
3996#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3997pub enum SubscribeRelation<T: AstInfo> {
3998 Name(T::ItemName),
3999 Query(Query<T>),
4000}
4001
4002impl<T: AstInfo> SubscribeRelation<T> {
4003 pub fn needs_explicit_to(&self, bare_identifiers: bool) -> bool {
4007 let SubscribeRelation::Name(name) = self else {
4008 return false;
4009 };
4010 bare_identifiers && name_starts_with_bare_to(&name.to_ast_string_simple())
4011 }
4012}
4013
4014fn name_starts_with_bare_to(name: &str) -> bool {
4015 let Some(rest) = name.strip_prefix("to") else {
4016 return false;
4017 };
4018 rest.is_empty() || rest.starts_with('.')
4019}
4020
4021impl<T: AstInfo> AstDisplay for SubscribeRelation<T> {
4022 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4023 match self {
4024 SubscribeRelation::Name(name) => f.write_node(name),
4025 SubscribeRelation::Query(query) => {
4026 f.write_str("(");
4027 f.write_node(query);
4028 f.write_str(")");
4029 }
4030 }
4031 }
4032}
4033impl_display_t!(SubscribeRelation);
4034
4035#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4036pub struct ExplainPlanStatement<T: AstInfo> {
4037 pub stage: Option<ExplainStage>,
4038 pub with_options: Vec<ExplainPlanOption<T>>,
4039 pub format: Option<ExplainFormat>,
4040 pub explainee: Explainee<T>,
4041}
4042
4043impl<T: AstInfo> ExplainPlanStatement<T> {
4044 pub fn stage(&self) -> ExplainStage {
4045 self.stage.unwrap_or(ExplainStage::PhysicalPlan)
4046 }
4047
4048 pub fn format(&self) -> ExplainFormat {
4049 self.format.unwrap_or(ExplainFormat::Text)
4050 }
4051}
4052
4053impl<T: AstInfo> AstDisplay for ExplainPlanStatement<T> {
4054 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4055 f.write_str("EXPLAIN");
4056 if let Some(stage) = &self.stage {
4057 f.write_str(" ");
4058 f.write_node(stage);
4059 }
4060 if !self.with_options.is_empty() {
4061 f.write_str(" WITH (");
4062 f.write_node(&display::comma_separated(&self.with_options));
4063 f.write_str(")");
4064 }
4065 if let Some(format) = &self.format {
4066 f.write_str(" AS ");
4067 f.write_node(format);
4068 }
4069 if self.stage.is_some() {
4070 f.write_str(" FOR");
4071 }
4072 f.write_str(" ");
4073 f.write_node(&self.explainee);
4074 }
4075}
4076impl_display_t!(ExplainPlanStatement);
4077
4078#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4081pub enum ExplainPlanOptionName {
4082 Arity,
4083 Cardinality,
4084 ColumnNames,
4085 FilterPushdown,
4086 HumanizedExpressions,
4087 JoinImplementations,
4088 Keys,
4089 LinearChains,
4090 NonNegative,
4091 NoFastPath,
4092 NoNotices,
4093 NodeIdentifiers,
4094 RawPlans,
4095 RawSyntax,
4096 Raw, Redacted,
4098 SubtreeSize,
4099 Timing,
4100 Types,
4101 Equivalences,
4102 ReoptimizeImportedViews,
4103 EnableNewOuterJoinLowering,
4104 EnableEagerDeltaJoins,
4105 EnableVariadicLeftJoinLowering,
4106 EnableLetrecFixpointAnalysis,
4107 EnableJoinPrioritizeArranged,
4108 EnableProjectionPushdownAfterRelationCse,
4109 EnableFixedCorrelatedCteLowering,
4110}
4111
4112impl WithOptionName for ExplainPlanOptionName {
4113 fn redact_value(&self) -> bool {
4119 match self {
4120 Self::Arity
4121 | Self::Cardinality
4122 | Self::ColumnNames
4123 | Self::FilterPushdown
4124 | Self::HumanizedExpressions
4125 | Self::JoinImplementations
4126 | Self::Keys
4127 | Self::LinearChains
4128 | Self::NonNegative
4129 | Self::NoFastPath
4130 | Self::NoNotices
4131 | Self::NodeIdentifiers
4132 | Self::RawPlans
4133 | Self::RawSyntax
4134 | Self::Raw
4135 | Self::Redacted
4136 | Self::SubtreeSize
4137 | Self::Timing
4138 | Self::Types
4139 | Self::Equivalences
4140 | Self::ReoptimizeImportedViews
4141 | Self::EnableNewOuterJoinLowering
4142 | Self::EnableEagerDeltaJoins
4143 | Self::EnableVariadicLeftJoinLowering
4144 | Self::EnableLetrecFixpointAnalysis
4145 | Self::EnableJoinPrioritizeArranged
4146 | Self::EnableProjectionPushdownAfterRelationCse
4147 | Self::EnableFixedCorrelatedCteLowering => false,
4148 }
4149 }
4150}
4151
4152#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4153pub struct ExplainPlanOption<T: AstInfo> {
4154 pub name: ExplainPlanOptionName,
4155 pub value: Option<WithOptionValue<T>>,
4156}
4157impl_display_for_with_option!(ExplainPlanOption);
4158
4159#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4160pub enum ExplainSinkSchemaFor {
4161 Key,
4162 Value,
4163}
4164#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4165pub struct ExplainSinkSchemaStatement<T: AstInfo> {
4166 pub schema_for: ExplainSinkSchemaFor,
4167 pub format: Option<ExplainFormat>,
4168 pub statement: CreateSinkStatement<T>,
4169}
4170
4171impl<T: AstInfo> AstDisplay for ExplainSinkSchemaStatement<T> {
4172 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4173 f.write_str("EXPLAIN ");
4174 match &self.schema_for {
4175 ExplainSinkSchemaFor::Key => f.write_str("KEY"),
4176 ExplainSinkSchemaFor::Value => f.write_str("VALUE"),
4177 }
4178 f.write_str(" SCHEMA");
4179 if let Some(format) = &self.format {
4180 f.write_str(" AS ");
4181 f.write_node(format);
4182 }
4183 f.write_str(" FOR ");
4184 f.write_node(&self.statement);
4185 }
4186}
4187impl_display_t!(ExplainSinkSchemaStatement);
4188
4189#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4190pub struct ExplainPushdownStatement<T: AstInfo> {
4191 pub explainee: Explainee<T>,
4192}
4193
4194impl<T: AstInfo> AstDisplay for ExplainPushdownStatement<T> {
4195 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4196 f.write_str("EXPLAIN FILTER PUSHDOWN FOR ");
4197 f.write_node(&self.explainee);
4198 }
4199}
4200impl_display_t!(ExplainPushdownStatement);
4201
4202#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
4203pub enum ExplainAnalyzeComputationProperty {
4204 Cpu,
4205 Memory,
4206}
4207
4208#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4209pub enum ExplainAnalyzeProperty {
4210 Computation(ExplainAnalyzeComputationProperties),
4211 Hints,
4212}
4213
4214#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4215pub struct ExplainAnalyzeComputationProperties {
4216 pub properties: Vec<ExplainAnalyzeComputationProperty>,
4218 pub skew: bool,
4219}
4220#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4221pub struct ExplainAnalyzeObjectStatement<T: AstInfo> {
4222 pub properties: ExplainAnalyzeProperty,
4223 pub explainee: Explainee<T>,
4225 pub as_sql: bool,
4226}
4227
4228impl<T: AstInfo> AstDisplay for ExplainAnalyzeObjectStatement<T> {
4229 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4230 f.write_str("EXPLAIN ANALYZE");
4231 match &self.properties {
4232 ExplainAnalyzeProperty::Computation(ExplainAnalyzeComputationProperties {
4233 properties,
4234 skew,
4235 }) => {
4236 let mut first = true;
4237 for property in properties {
4238 if first {
4239 first = false;
4240 } else {
4241 f.write_str(",");
4242 }
4243 match property {
4244 ExplainAnalyzeComputationProperty::Cpu => f.write_str(" CPU"),
4245 ExplainAnalyzeComputationProperty::Memory => f.write_str(" MEMORY"),
4246 }
4247 }
4248 if *skew {
4249 f.write_str(" WITH SKEW");
4250 }
4251 }
4252 ExplainAnalyzeProperty::Hints => f.write_str(" HINTS"),
4253 }
4254 f.write_str(" FOR ");
4255 f.write_node(&self.explainee);
4256 if self.as_sql {
4257 f.write_str(" AS SQL");
4258 }
4259 }
4260}
4261impl_display_t!(ExplainAnalyzeObjectStatement);
4262
4263#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4264pub struct ExplainAnalyzeClusterStatement {
4265 pub properties: ExplainAnalyzeComputationProperties,
4266 pub as_sql: bool,
4267}
4268
4269impl AstDisplay for ExplainAnalyzeClusterStatement {
4270 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4271 f.write_str("EXPLAIN ANALYZE CLUSTER");
4272
4273 let mut first = true;
4274 for property in &self.properties.properties {
4275 if first {
4276 first = false;
4277 } else {
4278 f.write_str(",");
4279 }
4280 match property {
4281 ExplainAnalyzeComputationProperty::Cpu => f.write_str(" CPU"),
4282 ExplainAnalyzeComputationProperty::Memory => f.write_str(" MEMORY"),
4283 }
4284 }
4285
4286 if self.properties.skew {
4287 f.write_str(" WITH SKEW");
4288 }
4289 if self.as_sql {
4290 f.write_str(" AS SQL");
4291 }
4292 }
4293}
4294impl_display!(ExplainAnalyzeClusterStatement);
4295
4296#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4297pub struct ExplainTimestampStatement<T: AstInfo> {
4298 pub format: Option<ExplainFormat>,
4299 pub select: SelectStatement<T>,
4300}
4301
4302impl<T: AstInfo> ExplainTimestampStatement<T> {
4303 pub fn format(&self) -> ExplainFormat {
4304 self.format.unwrap_or(ExplainFormat::Text)
4305 }
4306}
4307
4308impl<T: AstInfo> AstDisplay for ExplainTimestampStatement<T> {
4309 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4310 f.write_str("EXPLAIN TIMESTAMP");
4311 if let Some(format) = &self.format {
4312 f.write_str(" AS ");
4313 f.write_node(format);
4314 }
4315 f.write_str(" FOR ");
4316 f.write_node(&self.select);
4317 }
4318}
4319impl_display_t!(ExplainTimestampStatement);
4320
4321#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4322pub enum InsertSource<T: AstInfo> {
4323 Query(Query<T>),
4324 DefaultValues,
4325}
4326
4327impl<T: AstInfo> AstDisplay for InsertSource<T> {
4328 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4329 match self {
4330 InsertSource::Query(query) => f.write_node(query),
4331 InsertSource::DefaultValues => f.write_str("DEFAULT VALUES"),
4332 }
4333 }
4334}
4335impl_display_t!(InsertSource);
4336
4337#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
4338pub enum ObjectType {
4339 Table,
4340 View,
4341 MaterializedView,
4342 Source,
4343 Sink,
4344 Index,
4345 Type,
4346 Role,
4347 Cluster,
4348 ClusterReplica,
4349 Secret,
4350 Connection,
4351 Database,
4352 Schema,
4353 Func,
4354 Subsource,
4355 NetworkPolicy,
4356}
4357
4358impl ObjectType {
4359 pub fn lives_in_schema(&self) -> bool {
4360 match self {
4361 ObjectType::Table
4362 | ObjectType::View
4363 | ObjectType::MaterializedView
4364 | ObjectType::Source
4365 | ObjectType::Sink
4366 | ObjectType::Index
4367 | ObjectType::Type
4368 | ObjectType::Secret
4369 | ObjectType::Connection
4370 | ObjectType::Func
4371 | ObjectType::Subsource => true,
4372 ObjectType::Database
4373 | ObjectType::Schema
4374 | ObjectType::Cluster
4375 | ObjectType::ClusterReplica
4376 | ObjectType::Role
4377 | ObjectType::NetworkPolicy => false,
4378 }
4379 }
4380}
4381
4382impl AstDisplay for ObjectType {
4383 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4384 f.write_str(match self {
4385 ObjectType::Table => "TABLE",
4386 ObjectType::View => "VIEW",
4387 ObjectType::MaterializedView => "MATERIALIZED VIEW",
4388 ObjectType::Source => "SOURCE",
4389 ObjectType::Sink => "SINK",
4390 ObjectType::Index => "INDEX",
4391 ObjectType::Type => "TYPE",
4392 ObjectType::Role => "ROLE",
4393 ObjectType::Cluster => "CLUSTER",
4394 ObjectType::ClusterReplica => "CLUSTER REPLICA",
4395 ObjectType::Secret => "SECRET",
4396 ObjectType::Connection => "CONNECTION",
4397 ObjectType::Database => "DATABASE",
4398 ObjectType::Schema => "SCHEMA",
4399 ObjectType::Func => "FUNCTION",
4400 ObjectType::Subsource => "SUBSOURCE",
4401 ObjectType::NetworkPolicy => "NETWORK POLICY",
4402 })
4403 }
4404}
4405impl_display!(ObjectType);
4406
4407#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
4408pub enum SystemObjectType {
4409 System,
4410 Object(ObjectType),
4411}
4412
4413impl AstDisplay for SystemObjectType {
4414 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4415 match self {
4416 SystemObjectType::System => f.write_str("SYSTEM"),
4417 SystemObjectType::Object(object) => f.write_node(object),
4418 }
4419 }
4420}
4421impl_display!(SystemObjectType);
4422
4423#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4424pub enum ShowStatementFilter<T: AstInfo> {
4425 Like(String),
4426 Where(Expr<T>),
4427}
4428
4429impl<T: AstInfo> AstDisplay for ShowStatementFilter<T> {
4430 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4431 use ShowStatementFilter::*;
4432 match self {
4433 Like(pattern) => {
4434 f.write_str("LIKE '");
4435 f.write_node(&display::escape_single_quote_string(pattern));
4436 f.write_str("'");
4437 }
4438 Where(expr) => {
4439 f.write_str("WHERE ");
4440 f.write_node(expr);
4441 }
4442 }
4443 }
4444}
4445impl_display_t!(ShowStatementFilter);
4446
4447#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4448pub enum WithOptionValue<T: AstInfo> {
4449 Value(Value),
4450 DataType(T::DataType),
4451 Secret(T::ItemName),
4452 Item(T::ItemName),
4453 UnresolvedItemName(UnresolvedItemName),
4454 Ident(Ident),
4455 Sequence(Vec<WithOptionValue<T>>),
4456 Map(BTreeMap<String, WithOptionValue<T>>),
4457 Expr(Expr<T>),
4459 ClusterReplicas(Vec<ReplicaDefinition<T>>),
4460 ConnectionKafkaBroker(KafkaBroker<T>),
4461 ConnectionAwsPrivatelink(ConnectionDefaultAwsPrivatelink<T>),
4462 KafkaMatchingBrokerRule(KafkaMatchingBrokerRule<T>),
4463 RetainHistoryFor(Value),
4464 Refresh(RefreshOptionValue<T>),
4465 ClusterScheduleOptionValue(ClusterScheduleOptionValue),
4466 ClusterAutoScalingStrategyOptionValue(ClusterAutoScalingStrategyOptionValue),
4467 ClusterAlterStrategy(ClusterAlterOptionValue<T>),
4468 NetworkPolicyRules(Vec<NetworkPolicyRuleDefinition<T>>),
4469}
4470
4471impl<T: AstInfo> AstDisplay for WithOptionValue<T> {
4472 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4473 if f.redacted() {
4474 match self {
4477 WithOptionValue::Value(_)
4478 | WithOptionValue::Sequence(_)
4479 | WithOptionValue::Map(_)
4480 | WithOptionValue::RetainHistoryFor(_)
4481 | WithOptionValue::Refresh(_)
4482 | WithOptionValue::Expr(_) => {
4483 }
4485 WithOptionValue::ConnectionKafkaBroker(_) => {
4486 f.write_str("'<REDACTED>'");
4487 return;
4488 }
4489 WithOptionValue::Secret(_) => {}
4495 WithOptionValue::DataType(_)
4496 | WithOptionValue::Item(_)
4497 | WithOptionValue::UnresolvedItemName(_)
4498 | WithOptionValue::Ident(_)
4499 | WithOptionValue::ConnectionAwsPrivatelink(_)
4500 | WithOptionValue::KafkaMatchingBrokerRule(_)
4501 | WithOptionValue::ClusterReplicas(_)
4502 | WithOptionValue::ClusterScheduleOptionValue(_)
4503 | WithOptionValue::ClusterAutoScalingStrategyOptionValue(_)
4504 | WithOptionValue::ClusterAlterStrategy(_)
4505 | WithOptionValue::NetworkPolicyRules(_) => {
4506 }
4508 }
4509 }
4510 match self {
4511 WithOptionValue::Sequence(values) => {
4512 f.write_str("(");
4513 f.write_node(&display::comma_separated(values));
4514 f.write_str(")");
4515 }
4516 WithOptionValue::Map(values) => {
4517 f.write_str("MAP[");
4518 let len = values.len();
4519 for (i, (key, value)) in values.iter().enumerate() {
4520 f.write_str("'");
4521 f.write_node(&display::escape_single_quote_string(key));
4522 f.write_str("' => ");
4523 f.write_node(value);
4524 if i + 1 < len {
4525 f.write_str(", ");
4526 }
4527 }
4528 f.write_str("]");
4529 }
4530 WithOptionValue::Expr(e) => f.write_node(e),
4531 WithOptionValue::Value(value) => f.write_node(value),
4532 WithOptionValue::DataType(typ) => f.write_node(typ),
4533 WithOptionValue::Secret(name) => {
4534 f.write_str("SECRET ");
4535 f.write_node(name)
4536 }
4537 WithOptionValue::Item(obj) => f.write_node(obj),
4538 WithOptionValue::UnresolvedItemName(r) => f.write_node(r),
4539 WithOptionValue::Ident(r) => f.write_node(r),
4540 WithOptionValue::ClusterReplicas(replicas) => {
4541 f.write_str("(");
4542 f.write_node(&display::comma_separated(replicas));
4543 f.write_str(")");
4544 }
4545 WithOptionValue::NetworkPolicyRules(rules) => {
4546 f.write_str("(");
4547 f.write_node(&display::comma_separated(rules));
4548 f.write_str(")");
4549 }
4550 WithOptionValue::ConnectionAwsPrivatelink(aws_privatelink) => {
4551 f.write_node(aws_privatelink);
4552 }
4553 WithOptionValue::KafkaMatchingBrokerRule(rule) => {
4554 f.write_node(rule);
4555 }
4556 WithOptionValue::ConnectionKafkaBroker(broker) => {
4557 f.write_node(broker);
4558 }
4559 WithOptionValue::RetainHistoryFor(value) => {
4560 f.write_str("FOR ");
4561 f.write_node(value);
4562 }
4563 WithOptionValue::Refresh(opt) => f.write_node(opt),
4564 WithOptionValue::ClusterScheduleOptionValue(value) => f.write_node(value),
4565 WithOptionValue::ClusterAutoScalingStrategyOptionValue(value) => f.write_node(value),
4566 WithOptionValue::ClusterAlterStrategy(value) => f.write_node(value),
4567 }
4568 }
4569}
4570impl_display_t!(WithOptionValue);
4571
4572#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4573pub enum RefreshOptionValue<T: AstInfo> {
4574 OnCommit,
4575 AtCreation,
4576 At(RefreshAtOptionValue<T>),
4577 Every(RefreshEveryOptionValue<T>),
4578}
4579
4580#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4581pub struct RefreshAtOptionValue<T: AstInfo> {
4582 pub time: Expr<T>,
4584}
4585
4586#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4587pub struct RefreshEveryOptionValue<T: AstInfo> {
4588 pub interval: IntervalValue,
4590 pub aligned_to: Option<Expr<T>>,
4592}
4593
4594impl<T: AstInfo> AstDisplay for RefreshOptionValue<T> {
4595 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4596 match self {
4597 RefreshOptionValue::OnCommit => {
4598 f.write_str("ON COMMIT");
4599 }
4600 RefreshOptionValue::AtCreation => {
4601 f.write_str("AT CREATION");
4602 }
4603 RefreshOptionValue::At(RefreshAtOptionValue { time }) => {
4604 f.write_str("AT ");
4605 f.write_node(time);
4606 }
4607 RefreshOptionValue::Every(RefreshEveryOptionValue {
4608 interval,
4609 aligned_to,
4610 }) => {
4611 f.write_str("EVERY '");
4612 f.write_node(interval);
4613 if let Some(aligned_to) = aligned_to {
4614 f.write_str(" ALIGNED TO ");
4615 f.write_node(aligned_to)
4616 }
4617 }
4618 }
4619 }
4620}
4621
4622#[derive(
4623 Debug,
4624 Clone,
4625 PartialEq,
4626 Eq,
4627 Hash,
4628 PartialOrd,
4629 Ord,
4630 Deserialize,
4631 Serialize
4632)]
4633pub enum ClusterScheduleOptionValue {
4634 Manual,
4635 Refresh {
4636 hydration_time_estimate: Option<IntervalValue>,
4637 },
4638}
4639
4640impl Default for ClusterScheduleOptionValue {
4641 fn default() -> Self {
4642 ClusterScheduleOptionValue::Manual
4644 }
4645}
4646
4647impl AstDisplay for ClusterScheduleOptionValue {
4648 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4649 match self {
4650 ClusterScheduleOptionValue::Manual => {
4651 f.write_str("MANUAL");
4652 }
4653 ClusterScheduleOptionValue::Refresh {
4654 hydration_time_estimate,
4655 } => {
4656 f.write_str("ON REFRESH");
4657 if let Some(hydration_time_estimate) = hydration_time_estimate {
4658 f.write_str(" (HYDRATION TIME ESTIMATE = '");
4659 f.write_node(hydration_time_estimate);
4660 f.write_str(")");
4661 }
4662 }
4663 }
4664 }
4665}
4666
4667#[derive(
4673 Debug,
4674 Clone,
4675 PartialEq,
4676 Eq,
4677 Hash,
4678 PartialOrd,
4679 Ord,
4680 Deserialize,
4681 Serialize
4682)]
4683pub struct ClusterAutoScalingStrategyOptionValue {
4684 pub on_hydration: Option<OnHydrationOptionValue>,
4685}
4686
4687impl AstDisplay for ClusterAutoScalingStrategyOptionValue {
4688 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4689 f.write_str("(");
4690 if let Some(on_hydration) = &self.on_hydration {
4691 f.write_node(on_hydration);
4692 }
4693 f.write_str(")");
4694 }
4695}
4696
4697#[derive(
4701 Debug,
4702 Clone,
4703 PartialEq,
4704 Eq,
4705 Hash,
4706 PartialOrd,
4707 Ord,
4708 Deserialize,
4709 Serialize
4710)]
4711pub struct OnHydrationOptionValue {
4712 pub hydration_size: Value,
4713 pub linger_duration: Option<Value>,
4714}
4715
4716impl AstDisplay for OnHydrationOptionValue {
4717 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4718 f.write_str("ON HYDRATION (HYDRATION SIZE = ");
4719 f.write_node(&self.hydration_size);
4720 if let Some(linger_duration) = &self.linger_duration {
4721 f.write_str(", LINGER DURATION = ");
4722 f.write_node(linger_duration);
4723 }
4724 f.write_str(")");
4725 }
4726}
4727
4728#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4729pub enum TransactionMode {
4730 AccessMode(TransactionAccessMode),
4731 IsolationLevel(TransactionIsolationLevel),
4732}
4733
4734impl AstDisplay for TransactionMode {
4735 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4736 use TransactionMode::*;
4737 match self {
4738 AccessMode(access_mode) => f.write_node(access_mode),
4739 IsolationLevel(iso_level) => {
4740 f.write_str("ISOLATION LEVEL ");
4741 f.write_node(iso_level);
4742 }
4743 }
4744 }
4745}
4746impl_display!(TransactionMode);
4747
4748#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
4750pub enum TransactionAccessMode {
4751 ReadOnly,
4752 ReadWrite,
4753}
4754
4755impl AstDisplay for TransactionAccessMode {
4756 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4757 use TransactionAccessMode::*;
4758 f.write_str(match self {
4759 ReadOnly => "READ ONLY",
4760 ReadWrite => "READ WRITE",
4761 })
4762 }
4763}
4764impl_display!(TransactionAccessMode);
4765
4766#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
4767pub enum TransactionIsolationLevel {
4768 ReadUncommitted,
4769 ReadCommitted,
4770 RepeatableRead,
4771 Serializable,
4772 StrongSessionSerializable,
4773 StrictSerializable,
4774}
4775
4776impl AstDisplay for TransactionIsolationLevel {
4777 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4778 use TransactionIsolationLevel::*;
4779 f.write_str(match self {
4780 ReadUncommitted => "READ UNCOMMITTED",
4781 ReadCommitted => "READ COMMITTED",
4782 RepeatableRead => "REPEATABLE READ",
4783 Serializable => "SERIALIZABLE",
4784 StrongSessionSerializable => "STRONG SESSION SERIALIZABLE",
4785 StrictSerializable => "STRICT SERIALIZABLE",
4786 })
4787 }
4788}
4789impl_display!(TransactionIsolationLevel);
4790
4791#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4792pub enum SetVariableTo {
4793 Default,
4794 Values(Vec<SetVariableValue>),
4795}
4796
4797impl AstDisplay for SetVariableTo {
4798 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4799 use SetVariableTo::*;
4800 match self {
4801 Values(values) => f.write_node(&display::comma_separated(values)),
4802 Default => f.write_str("DEFAULT"),
4803 }
4804 }
4805}
4806impl_display!(SetVariableTo);
4807
4808#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4809pub enum SetVariableValue {
4810 Ident(Ident),
4811 Literal(Value),
4812}
4813
4814impl AstDisplay for SetVariableValue {
4815 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4816 use SetVariableValue::*;
4817 match self {
4818 Ident(ident) => f.write_node(ident),
4819 Literal(literal) => f.write_node(literal),
4820 }
4821 }
4822}
4823impl_display!(SetVariableValue);
4824
4825impl SetVariableValue {
4826 pub fn into_unquoted_value(self) -> String {
4828 match self {
4829 SetVariableValue::Literal(Value::String(s)) => s,
4832 SetVariableValue::Literal(lit) => lit.to_string(),
4833 SetVariableValue::Ident(ident) => ident.into_string(),
4834 }
4835 }
4836}
4837
4838#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4840pub struct Assignment<T: AstInfo> {
4841 pub id: Ident,
4842 pub value: Expr<T>,
4843}
4844
4845impl<T: AstInfo> AstDisplay for Assignment<T> {
4846 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4847 f.write_node(&self.id);
4848 f.write_str(" = ");
4849 f.write_node(&self.value);
4850 }
4851}
4852impl_display_t!(Assignment);
4853
4854#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4856pub enum ExplainStage {
4857 RawPlan,
4859 DecorrelatedPlan,
4861 LocalPlan,
4863 GlobalPlan,
4865 PhysicalPlan,
4867 Trace,
4869 PlanInsights,
4871}
4872
4873impl ExplainStage {
4874 pub fn paths(&self) -> Option<SmallVec<[NamedPlan; 4]>> {
4876 use NamedPlan::*;
4877 match self {
4878 Self::RawPlan => Some(smallvec![Raw]),
4879 Self::DecorrelatedPlan => Some(smallvec![Decorrelated]),
4880 Self::LocalPlan => Some(smallvec![Local]),
4881 Self::GlobalPlan => Some(smallvec![Global]),
4882 Self::PhysicalPlan => Some(smallvec![Physical]),
4883 Self::Trace => None,
4884 Self::PlanInsights => Some(smallvec![Raw, Global, FastPath]),
4885 }
4886 }
4887
4888 pub fn show_fast_path(&self) -> bool {
4891 match self {
4892 Self::RawPlan => false,
4893 Self::DecorrelatedPlan => false,
4894 Self::LocalPlan => false,
4895 Self::GlobalPlan => true,
4896 Self::PhysicalPlan => true,
4897 Self::Trace => false,
4898 Self::PlanInsights => false,
4899 }
4900 }
4901}
4902
4903impl AstDisplay for ExplainStage {
4904 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
4905 match self {
4906 Self::RawPlan => f.write_str("RAW PLAN"),
4907 Self::DecorrelatedPlan => f.write_str("DECORRELATED PLAN"),
4908 Self::LocalPlan => f.write_str("LOCALLY OPTIMIZED PLAN"),
4909 Self::GlobalPlan => f.write_str("OPTIMIZED PLAN"),
4910 Self::PhysicalPlan => f.write_str("PHYSICAL PLAN"),
4911 Self::Trace => f.write_str("OPTIMIZER TRACE"),
4912 Self::PlanInsights => f.write_str("PLAN INSIGHTS"),
4913 }
4914 }
4915}
4916impl_display!(ExplainStage);
4917
4918#[derive(Clone)]
4921pub enum NamedPlan {
4922 Raw,
4923 Decorrelated,
4924 Local,
4925 Global,
4926 Physical,
4927 FastPath,
4928}
4929
4930impl NamedPlan {
4931 pub fn of_path(value: &str) -> Option<Self> {
4933 match value {
4934 "optimize/raw" => Some(Self::Raw),
4935 "optimize/hir_to_mir" => Some(Self::Decorrelated),
4936 "optimize/local" => Some(Self::Local),
4937 "optimize/global" => Some(Self::Global),
4938 "optimize/finalize_dataflow" => Some(Self::Physical),
4939 "optimize/fast_path" => Some(Self::FastPath),
4940 _ => None,
4941 }
4942 }
4943
4944 pub fn path(&self) -> &'static str {
4947 match self {
4948 Self::Raw => "optimize/raw",
4949 Self::Decorrelated => "optimize/hir_to_mir",
4950 Self::Local => "optimize/local",
4951 Self::Global => "optimize/global",
4952 Self::Physical => "optimize/finalize_dataflow",
4953 Self::FastPath => "optimize/fast_path",
4954 }
4955 }
4956}
4957
4958#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4961pub enum Explainee<T: AstInfo> {
4962 View(T::ItemName),
4963 MaterializedView(T::ItemName),
4964 Index(T::ItemName),
4965 ReplanView(T::ItemName),
4966 ReplanMaterializedView(T::ItemName),
4967 ReplanIndex(T::ItemName),
4968 Select(Box<SelectStatement<T>>, bool),
4969 CreateView(Box<CreateViewStatement<T>>, bool),
4970 CreateMaterializedView(Box<CreateMaterializedViewStatement<T>>, bool),
4971 CreateIndex(Box<CreateIndexStatement<T>>, bool),
4972 Subscribe(Box<SubscribeStatement<T>>, bool),
4973}
4974
4975impl<T: AstInfo> Explainee<T> {
4976 pub fn name(&self) -> Option<&T::ItemName> {
4977 match self {
4978 Self::View(name)
4979 | Self::ReplanView(name)
4980 | Self::MaterializedView(name)
4981 | Self::ReplanMaterializedView(name)
4982 | Self::Index(name)
4983 | Self::ReplanIndex(name) => Some(name),
4984 Self::Select(..)
4985 | Self::CreateView(..)
4986 | Self::CreateMaterializedView(..)
4987 | Self::CreateIndex(..)
4988 | Self::Subscribe(..) => None,
4989 }
4990 }
4991
4992 pub fn is_view(&self) -> bool {
4993 use Explainee::*;
4994 matches!(self, View(_) | ReplanView(_) | CreateView(_, _))
4995 }
4996}
4997
4998impl<T: AstInfo> AstDisplay for Explainee<T> {
4999 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5000 match self {
5001 Self::View(name) => {
5002 f.write_str("VIEW ");
5003 f.write_node(name);
5004 }
5005 Self::MaterializedView(name) => {
5006 f.write_str("MATERIALIZED VIEW ");
5007 f.write_node(name);
5008 }
5009 Self::Index(name) => {
5010 f.write_str("INDEX ");
5011 f.write_node(name);
5012 }
5013 Self::ReplanView(name) => {
5014 f.write_str("REPLAN VIEW ");
5015 f.write_node(name);
5016 }
5017 Self::ReplanMaterializedView(name) => {
5018 f.write_str("REPLAN MATERIALIZED VIEW ");
5019 f.write_node(name);
5020 }
5021 Self::ReplanIndex(name) => {
5022 f.write_str("REPLAN INDEX ");
5023 f.write_node(name);
5024 }
5025 Self::Select(select, broken) => {
5026 if *broken {
5027 f.write_str("BROKEN ");
5028 }
5029 f.write_node(select);
5030 }
5031 Self::CreateView(statement, broken) => {
5032 if *broken {
5033 f.write_str("BROKEN ");
5034 }
5035 f.write_node(statement);
5036 }
5037 Self::CreateMaterializedView(statement, broken) => {
5038 if *broken {
5039 f.write_str("BROKEN ");
5040 }
5041 f.write_node(statement);
5042 }
5043 Self::CreateIndex(statement, broken) => {
5044 if *broken {
5045 f.write_str("BROKEN ");
5046 }
5047 f.write_node(statement);
5048 }
5049 Self::Subscribe(statement, broken) => {
5050 if *broken {
5051 f.write_str("BROKEN ");
5052 }
5053 f.write_node(statement);
5054 }
5055 }
5056 }
5057}
5058impl_display_t!(Explainee);
5059
5060#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
5061pub enum ExplainFormat {
5062 Text,
5064 VerboseText,
5066 Json,
5068 Dot,
5070}
5071
5072impl AstDisplay for ExplainFormat {
5073 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5074 match self {
5075 Self::Text => f.write_str("TEXT"),
5076 Self::VerboseText => f.write_str("VERBOSE TEXT"),
5077 Self::Json => f.write_str("JSON"),
5078 Self::Dot => f.write_str("DOT"),
5079 }
5080 }
5081}
5082impl_display!(ExplainFormat);
5083
5084#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5085pub enum IfExistsBehavior {
5086 Error,
5087 Skip,
5088 Replace,
5089}
5090
5091#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5093pub struct DeclareStatement<T: AstInfo> {
5094 pub name: Ident,
5095 pub stmt: Box<T::NestedStatement>,
5096 pub sql: String,
5097}
5098
5099impl<T: AstInfo> AstDisplay for DeclareStatement<T> {
5100 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5101 f.write_str("DECLARE ");
5102 f.write_node(&self.name);
5103 f.write_str(" CURSOR FOR ");
5104 f.write_node(&self.stmt);
5105 }
5106}
5107impl_display_t!(DeclareStatement);
5108
5109#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5111pub struct CloseStatement {
5112 pub name: Ident,
5113}
5114
5115impl AstDisplay for CloseStatement {
5116 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5117 f.write_str("CLOSE ");
5118 f.write_node(&self.name);
5119 }
5120}
5121impl_display!(CloseStatement);
5122
5123#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5124pub enum FetchOptionName {
5125 Timeout,
5126}
5127
5128impl AstDisplay for FetchOptionName {
5129 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5130 f.write_str(match self {
5131 FetchOptionName::Timeout => "TIMEOUT",
5132 })
5133 }
5134}
5135
5136impl WithOptionName for FetchOptionName {
5137 fn redact_value(&self) -> bool {
5143 match self {
5144 FetchOptionName::Timeout => false,
5145 }
5146 }
5147}
5148
5149#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5150pub struct FetchOption<T: AstInfo> {
5151 pub name: FetchOptionName,
5152 pub value: Option<WithOptionValue<T>>,
5153}
5154impl_display_for_with_option!(FetchOption);
5155
5156#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5158pub struct FetchStatement<T: AstInfo> {
5159 pub name: Ident,
5160 pub count: Option<FetchDirection>,
5161 pub options: Vec<FetchOption<T>>,
5162}
5163
5164impl<T: AstInfo> AstDisplay for FetchStatement<T> {
5165 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5166 f.write_str("FETCH ");
5167 if let Some(ref count) = self.count {
5168 f.write_str(format!("{} ", count));
5169 }
5170 if self.count.is_none() && self.name.as_str().eq_ignore_ascii_case("forward") {
5174 f.write_str(self.name.to_ast_string_stable());
5175 } else {
5176 f.write_node(&self.name);
5177 }
5178 if !self.options.is_empty() {
5179 f.write_str(" WITH (");
5180 f.write_node(&display::comma_separated(&self.options));
5181 f.write_str(")");
5182 }
5183 }
5184}
5185impl_display_t!(FetchStatement);
5186
5187#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5188pub enum FetchDirection {
5189 ForwardAll,
5190 ForwardCount(u64),
5191}
5192
5193impl AstDisplay for FetchDirection {
5194 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5195 match self {
5196 FetchDirection::ForwardAll => f.write_str("ALL"),
5197 FetchDirection::ForwardCount(count) => f.write_str(format!("{}", count)),
5198 }
5199 }
5200}
5201impl_display!(FetchDirection);
5202
5203#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5205pub struct PrepareStatement<T: AstInfo> {
5206 pub name: Ident,
5207 pub stmt: Box<T::NestedStatement>,
5208 pub sql: String,
5209}
5210
5211impl<T: AstInfo> AstDisplay for PrepareStatement<T> {
5212 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5213 f.write_str("PREPARE ");
5214 f.write_node(&self.name);
5215 f.write_str(" AS ");
5216 f.write_node(&self.stmt);
5217 }
5218}
5219impl_display_t!(PrepareStatement);
5220
5221#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5223pub struct ExecuteStatement<T: AstInfo> {
5224 pub name: Ident,
5225 pub params: Vec<Expr<T>>,
5226}
5227
5228impl<T: AstInfo> AstDisplay for ExecuteStatement<T> {
5229 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5230 f.write_str("EXECUTE ");
5231 f.write_node(&self.name);
5232 if !self.params.is_empty() {
5233 f.write_str(" (");
5234 f.write_node(&display::comma_separated(&self.params));
5235 f.write_str(")");
5236 }
5237 }
5238}
5239impl_display_t!(ExecuteStatement);
5240
5241#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5243pub struct ExecuteUnitTestStatement<T: AstInfo> {
5244 pub name: Ident,
5245 pub target: T::ItemName,
5246 pub at_time: Option<Expr<T>>,
5247 pub mocks: Vec<MockViewDef<T>>,
5248 pub expected: ExpectedResultDef<T>,
5249}
5250
5251impl<T: AstInfo> AstDisplay for ExecuteUnitTestStatement<T> {
5252 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5253 f.write_str("EXECUTE UNIT TEST ");
5254 f.write_node(&self.name);
5255 f.write_str(" FOR ");
5256 f.write_node(&self.target);
5257 if let Some(at_time) = &self.at_time {
5258 f.write_str(" AT TIME ");
5259 f.write_node(at_time);
5260 }
5261 for (i, mock) in self.mocks.iter().enumerate() {
5262 f.write_str(if i == 0 { " MOCK " } else { ", MOCK " });
5263 f.write_node(mock);
5264 }
5265 f.write_str(" EXPECTED ");
5266 f.write_node(&self.expected);
5267 }
5268}
5269impl_display_t!(ExecuteUnitTestStatement);
5270
5271#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5273pub struct MockViewDef<T: AstInfo> {
5274 pub name: T::ItemName,
5275 pub columns: Vec<ColumnDef<T>>,
5276 pub query: Query<T>,
5277}
5278
5279impl<T: AstInfo> AstDisplay for MockViewDef<T> {
5280 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5281 f.write_node(&self.name);
5282 f.write_str("(");
5283 f.write_node(&display::comma_separated(&self.columns));
5284 f.write_str(") AS (");
5285 f.write_node(&self.query);
5286 f.write_str(")");
5287 }
5288}
5289impl_display_t!(MockViewDef);
5290
5291#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5293pub struct ExpectedResultDef<T: AstInfo> {
5294 pub columns: Vec<ColumnDef<T>>,
5295 pub query: Query<T>,
5296}
5297
5298impl<T: AstInfo> AstDisplay for ExpectedResultDef<T> {
5299 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5300 f.write_str("(");
5301 f.write_node(&display::comma_separated(&self.columns));
5302 f.write_str(") AS (");
5303 f.write_node(&self.query);
5304 f.write_str(")");
5305 }
5306}
5307impl_display_t!(ExpectedResultDef);
5308
5309#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5311pub struct DeallocateStatement {
5312 pub name: Option<Ident>,
5313}
5314
5315impl AstDisplay for DeallocateStatement {
5316 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5317 f.write_str("DEALLOCATE ");
5318 match &self.name {
5319 Some(name) => f.write_node(name),
5320 None => f.write_str("ALL"),
5321 };
5322 }
5323}
5324impl_display!(DeallocateStatement);
5325
5326#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5328pub struct RaiseStatement {
5329 pub severity: NoticeSeverity,
5330}
5331
5332impl AstDisplay for RaiseStatement {
5333 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5334 f.write_str("RAISE ");
5335 f.write_node(&self.severity);
5336 }
5337}
5338impl_display!(RaiseStatement);
5339
5340#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5341pub enum NoticeSeverity {
5342 Debug,
5343 Info,
5344 Log,
5345 Notice,
5346 Warning,
5347}
5348
5349impl AstDisplay for NoticeSeverity {
5350 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5351 f.write_str(match self {
5352 NoticeSeverity::Debug => "DEBUG",
5353 NoticeSeverity::Info => "INFO",
5354 NoticeSeverity::Log => "LOG",
5355 NoticeSeverity::Notice => "NOTICE",
5356 NoticeSeverity::Warning => "WARNING",
5357 })
5358 }
5359}
5360impl_display!(NoticeSeverity);
5361
5362#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5364pub struct AlterSystemSetStatement {
5365 pub name: Ident,
5366 pub to: SetVariableTo,
5367}
5368
5369impl AstDisplay for AlterSystemSetStatement {
5370 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5371 f.write_str("ALTER SYSTEM SET ");
5372 f.write_node(&self.name);
5373 f.write_str(" = ");
5374 f.write_node(&self.to);
5375 }
5376}
5377impl_display!(AlterSystemSetStatement);
5378
5379#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5381pub struct AlterSystemResetStatement {
5382 pub name: Ident,
5383}
5384
5385impl AstDisplay for AlterSystemResetStatement {
5386 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5387 f.write_str("ALTER SYSTEM RESET ");
5388 f.write_node(&self.name);
5389 }
5390}
5391impl_display!(AlterSystemResetStatement);
5392
5393#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5395pub struct AlterSystemResetAllStatement {}
5396
5397impl AstDisplay for AlterSystemResetAllStatement {
5398 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5399 f.write_str("ALTER SYSTEM RESET ALL");
5400 }
5401}
5402impl_display!(AlterSystemResetAllStatement);
5403
5404#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5405pub enum AsOf<T: AstInfo> {
5406 At(Expr<T>),
5407 AtLeast(Expr<T>),
5408}
5409
5410impl<T: AstInfo> AstDisplay for AsOf<T> {
5411 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5412 f.write_str("AS OF ");
5413 match self {
5414 AsOf::At(expr) => f.write_node(expr),
5415 AsOf::AtLeast(expr) => {
5416 f.write_str("AT LEAST ");
5417 f.write_node(expr);
5418 }
5419 }
5420 }
5421}
5422impl_display_t!(AsOf);
5423
5424#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
5425pub enum ShowStatement<T: AstInfo> {
5426 ShowObjects(ShowObjectsStatement<T>),
5427 ShowColumns(ShowColumnsStatement<T>),
5428 ShowCreateView(ShowCreateViewStatement<T>),
5429 ShowCreateMaterializedView(ShowCreateMaterializedViewStatement<T>),
5430 ShowCreateSource(ShowCreateSourceStatement<T>),
5431 ShowCreateTable(ShowCreateTableStatement<T>),
5432 ShowCreateSink(ShowCreateSinkStatement<T>),
5433 ShowCreateIndex(ShowCreateIndexStatement<T>),
5434 ShowCreateConnection(ShowCreateConnectionStatement<T>),
5435 ShowCreateCluster(ShowCreateClusterStatement<T>),
5436 ShowCreateType(ShowCreateTypeStatement<T>),
5437 ShowVariable(ShowVariableStatement),
5438 InspectShard(InspectShardStatement),
5439}
5440
5441impl<T: AstInfo> AstDisplay for ShowStatement<T> {
5442 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5443 match self {
5444 ShowStatement::ShowObjects(stmt) => f.write_node(stmt),
5445 ShowStatement::ShowColumns(stmt) => f.write_node(stmt),
5446 ShowStatement::ShowCreateView(stmt) => f.write_node(stmt),
5447 ShowStatement::ShowCreateMaterializedView(stmt) => f.write_node(stmt),
5448 ShowStatement::ShowCreateSource(stmt) => f.write_node(stmt),
5449 ShowStatement::ShowCreateTable(stmt) => f.write_node(stmt),
5450 ShowStatement::ShowCreateSink(stmt) => f.write_node(stmt),
5451 ShowStatement::ShowCreateIndex(stmt) => f.write_node(stmt),
5452 ShowStatement::ShowCreateConnection(stmt) => f.write_node(stmt),
5453 ShowStatement::ShowCreateCluster(stmt) => f.write_node(stmt),
5454 ShowStatement::ShowCreateType(stmt) => f.write_node(stmt),
5455 ShowStatement::ShowVariable(stmt) => f.write_node(stmt),
5456 ShowStatement::InspectShard(stmt) => f.write_node(stmt),
5457 }
5458 }
5459}
5460impl_display_t!(ShowStatement);
5461
5462#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5464pub struct GrantRoleStatement<T: AstInfo> {
5465 pub role_names: Vec<T::RoleName>,
5467 pub member_names: Vec<T::RoleName>,
5469}
5470
5471impl<T: AstInfo> AstDisplay for GrantRoleStatement<T> {
5472 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5473 f.write_str("GRANT ");
5474 f.write_node(&display::comma_separated(&self.role_names));
5475 f.write_str(" TO ");
5476 f.write_node(&display::comma_separated(&self.member_names));
5477 }
5478}
5479impl_display_t!(GrantRoleStatement);
5480
5481#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5483pub struct RevokeRoleStatement<T: AstInfo> {
5484 pub role_names: Vec<T::RoleName>,
5486 pub member_names: Vec<T::RoleName>,
5488}
5489
5490impl<T: AstInfo> AstDisplay for RevokeRoleStatement<T> {
5491 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5492 f.write_str("REVOKE ");
5493 f.write_node(&display::comma_separated(&self.role_names));
5494 f.write_str(" FROM ");
5495 f.write_node(&display::comma_separated(&self.member_names));
5496 }
5497}
5498impl_display_t!(RevokeRoleStatement);
5499
5500#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5501pub enum Privilege {
5502 SELECT,
5503 INSERT,
5504 UPDATE,
5505 DELETE,
5506 USAGE,
5507 CREATE,
5508 CREATEROLE,
5509 CREATEDB,
5510 CREATECLUSTER,
5511 CREATENETWORKPOLICY,
5512}
5513
5514impl AstDisplay for Privilege {
5515 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5516 f.write_str(match self {
5517 Privilege::SELECT => "SELECT",
5518 Privilege::INSERT => "INSERT",
5519 Privilege::UPDATE => "UPDATE",
5520 Privilege::DELETE => "DELETE",
5521 Privilege::CREATE => "CREATE",
5522 Privilege::USAGE => "USAGE",
5523 Privilege::CREATEROLE => "CREATEROLE",
5524 Privilege::CREATEDB => "CREATEDB",
5525 Privilege::CREATECLUSTER => "CREATECLUSTER",
5526 Privilege::CREATENETWORKPOLICY => "CREATENETWORKPOLICY",
5527 });
5528 }
5529}
5530impl_display!(Privilege);
5531
5532#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5533pub enum PrivilegeSpecification {
5534 All,
5535 Privileges(Vec<Privilege>),
5536}
5537
5538impl AstDisplay for PrivilegeSpecification {
5539 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5540 match self {
5541 PrivilegeSpecification::All => f.write_str("ALL"),
5542 PrivilegeSpecification::Privileges(privileges) => {
5543 f.write_node(&display::comma_separated(privileges))
5544 }
5545 }
5546 }
5547}
5548impl_display!(PrivilegeSpecification);
5549
5550#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5551pub enum GrantTargetSpecification<T: AstInfo> {
5552 Object {
5553 object_type: ObjectType,
5557 object_spec_inner: GrantTargetSpecificationInner<T>,
5559 },
5560 System,
5561}
5562
5563#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5564pub enum GrantTargetSpecificationInner<T: AstInfo> {
5565 All(GrantTargetAllSpecification<T>),
5566 Objects { names: Vec<T::ObjectName> },
5567}
5568
5569#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5570pub enum GrantTargetAllSpecification<T: AstInfo> {
5571 All,
5572 AllDatabases { databases: Vec<T::DatabaseName> },
5573 AllSchemas { schemas: Vec<T::SchemaName> },
5574}
5575
5576impl<T: AstInfo> GrantTargetAllSpecification<T> {
5577 pub fn len(&self) -> usize {
5578 match self {
5579 GrantTargetAllSpecification::All => 1,
5580 GrantTargetAllSpecification::AllDatabases { databases } => databases.len(),
5581 GrantTargetAllSpecification::AllSchemas { schemas } => schemas.len(),
5582 }
5583 }
5584}
5585
5586fn write_grant_object_type_plural<W: fmt::Write>(
5592 f: &mut AstFormatter<W>,
5593 object_type: &ObjectType,
5594) {
5595 match object_type {
5596 ObjectType::NetworkPolicy => f.write_str("POLICIES"),
5597 other => {
5598 f.write_node(other);
5599 f.write_str("S");
5600 }
5601 }
5602}
5603
5604impl<T: AstInfo> AstDisplay for GrantTargetSpecification<T> {
5605 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5606 match self {
5607 GrantTargetSpecification::Object {
5608 object_type,
5609 object_spec_inner,
5610 } => match object_spec_inner {
5611 GrantTargetSpecificationInner::All(all_spec) => match all_spec {
5612 GrantTargetAllSpecification::All => {
5613 f.write_str("ALL ");
5614 write_grant_object_type_plural(f, object_type);
5615 }
5616 GrantTargetAllSpecification::AllDatabases { databases } => {
5617 f.write_str("ALL ");
5618 write_grant_object_type_plural(f, object_type);
5619 f.write_str(" IN DATABASE ");
5620 f.write_node(&display::comma_separated(databases));
5621 }
5622 GrantTargetAllSpecification::AllSchemas { schemas } => {
5623 f.write_str("ALL ");
5624 write_grant_object_type_plural(f, object_type);
5625 f.write_str(" IN SCHEMA ");
5626 f.write_node(&display::comma_separated(schemas));
5627 }
5628 },
5629 GrantTargetSpecificationInner::Objects { names } => {
5630 f.write_node(object_type);
5631 f.write_str(" ");
5632 f.write_node(&display::comma_separated(names));
5633 }
5634 },
5635 GrantTargetSpecification::System => f.write_str("SYSTEM"),
5636 }
5637 }
5638}
5639impl_display_t!(GrantTargetSpecification);
5640
5641#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5643pub struct GrantPrivilegesStatement<T: AstInfo> {
5644 pub privileges: PrivilegeSpecification,
5646 pub target: GrantTargetSpecification<T>,
5648 pub roles: Vec<T::RoleName>,
5650}
5651
5652impl<T: AstInfo> AstDisplay for GrantPrivilegesStatement<T> {
5653 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5654 f.write_str("GRANT ");
5655 f.write_node(&self.privileges);
5656 f.write_str(" ON ");
5657 f.write_node(&self.target);
5658 f.write_str(" TO ");
5659 f.write_node(&display::comma_separated(&self.roles));
5660 }
5661}
5662impl_display_t!(GrantPrivilegesStatement);
5663
5664#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5666pub struct RevokePrivilegesStatement<T: AstInfo> {
5667 pub privileges: PrivilegeSpecification,
5669 pub target: GrantTargetSpecification<T>,
5671 pub roles: Vec<T::RoleName>,
5673}
5674
5675impl<T: AstInfo> AstDisplay for RevokePrivilegesStatement<T> {
5676 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5677 f.write_str("REVOKE ");
5678 f.write_node(&self.privileges);
5679 f.write_str(" ON ");
5680 f.write_node(&self.target);
5681 f.write_str(" FROM ");
5682 f.write_node(&display::comma_separated(&self.roles));
5683 }
5684}
5685impl_display_t!(RevokePrivilegesStatement);
5686
5687#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5688pub enum TargetRoleSpecification<T: AstInfo> {
5689 Roles(Vec<T::RoleName>),
5691 AllRoles,
5693}
5694
5695impl<T: AstInfo> AstDisplay for TargetRoleSpecification<T> {
5696 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5697 match self {
5698 TargetRoleSpecification::Roles(roles) => f.write_node(&display::comma_separated(roles)),
5699 TargetRoleSpecification::AllRoles => f.write_str("ALL ROLES"),
5700 }
5701 }
5702}
5703impl_display_t!(TargetRoleSpecification);
5704
5705#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5706pub struct AbbreviatedGrantStatement<T: AstInfo> {
5707 pub privileges: PrivilegeSpecification,
5709 pub object_type: ObjectType,
5713 pub grantees: Vec<T::RoleName>,
5715}
5716
5717impl<T: AstInfo> AstDisplay for AbbreviatedGrantStatement<T> {
5718 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5719 f.write_str("GRANT ");
5720 f.write_node(&self.privileges);
5721 f.write_str(" ON ");
5722 f.write_node(&self.object_type);
5723 f.write_str("S TO ");
5724 f.write_node(&display::comma_separated(&self.grantees));
5725 }
5726}
5727impl_display_t!(AbbreviatedGrantStatement);
5728
5729#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5730pub struct AbbreviatedRevokeStatement<T: AstInfo> {
5731 pub privileges: PrivilegeSpecification,
5733 pub object_type: ObjectType,
5737 pub revokees: Vec<T::RoleName>,
5739}
5740
5741impl<T: AstInfo> AstDisplay for AbbreviatedRevokeStatement<T> {
5742 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5743 f.write_str("REVOKE ");
5744 f.write_node(&self.privileges);
5745 f.write_str(" ON ");
5746 f.write_node(&self.object_type);
5747 f.write_str("S FROM ");
5748 f.write_node(&display::comma_separated(&self.revokees));
5749 }
5750}
5751impl_display_t!(AbbreviatedRevokeStatement);
5752
5753#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5754pub enum AbbreviatedGrantOrRevokeStatement<T: AstInfo> {
5755 Grant(AbbreviatedGrantStatement<T>),
5756 Revoke(AbbreviatedRevokeStatement<T>),
5757}
5758
5759impl<T: AstInfo> AbbreviatedGrantOrRevokeStatement<T> {
5760 pub fn privileges(&self) -> &PrivilegeSpecification {
5761 match self {
5762 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.privileges,
5763 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.privileges,
5764 }
5765 }
5766
5767 pub fn object_type(&self) -> &ObjectType {
5768 match self {
5769 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.object_type,
5770 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.object_type,
5771 }
5772 }
5773
5774 pub fn roles(&self) -> &Vec<T::RoleName> {
5775 match self {
5776 AbbreviatedGrantOrRevokeStatement::Grant(grant) => &grant.grantees,
5777 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => &revoke.revokees,
5778 }
5779 }
5780}
5781
5782impl<T: AstInfo> AstDisplay for AbbreviatedGrantOrRevokeStatement<T> {
5783 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5784 match self {
5785 AbbreviatedGrantOrRevokeStatement::Grant(grant) => f.write_node(grant),
5786 AbbreviatedGrantOrRevokeStatement::Revoke(revoke) => f.write_node(revoke),
5787 }
5788 }
5789}
5790impl_display_t!(AbbreviatedGrantOrRevokeStatement);
5791
5792#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5794pub struct AlterDefaultPrivilegesStatement<T: AstInfo> {
5795 pub target_roles: TargetRoleSpecification<T>,
5797 pub target_objects: GrantTargetAllSpecification<T>,
5799 pub grant_or_revoke: AbbreviatedGrantOrRevokeStatement<T>,
5801}
5802
5803impl<T: AstInfo> AstDisplay for AlterDefaultPrivilegesStatement<T> {
5804 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5805 f.write_str("ALTER DEFAULT PRIVILEGES");
5806 match &self.target_roles {
5807 TargetRoleSpecification::Roles(_) => {
5808 f.write_str(" FOR ROLE ");
5809 f.write_node(&self.target_roles);
5810 }
5811 TargetRoleSpecification::AllRoles => {
5812 f.write_str(" FOR ");
5813 f.write_node(&self.target_roles);
5814 }
5815 }
5816 match &self.target_objects {
5817 GrantTargetAllSpecification::All => {}
5818 GrantTargetAllSpecification::AllDatabases { databases } => {
5819 f.write_str(" IN DATABASE ");
5820 f.write_node(&display::comma_separated(databases));
5821 }
5822 GrantTargetAllSpecification::AllSchemas { schemas } => {
5823 f.write_str(" IN SCHEMA ");
5824 f.write_node(&display::comma_separated(schemas));
5825 }
5826 }
5827 f.write_str(" ");
5828 f.write_node(&self.grant_or_revoke);
5829 }
5830}
5831impl_display_t!(AlterDefaultPrivilegesStatement);
5832
5833#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5835pub struct ReassignOwnedStatement<T: AstInfo> {
5836 pub old_roles: Vec<T::RoleName>,
5838 pub new_role: T::RoleName,
5840}
5841
5842impl<T: AstInfo> AstDisplay for ReassignOwnedStatement<T> {
5843 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5844 f.write_str("REASSIGN OWNED BY ");
5845 f.write_node(&display::comma_separated(&self.old_roles));
5846 f.write_str(" TO ");
5847 f.write_node(&self.new_role);
5848 }
5849}
5850impl_display_t!(ReassignOwnedStatement);
5851
5852#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5854pub struct CommentStatement<T: AstInfo> {
5855 pub object: CommentObjectType<T>,
5856 pub comment: Option<String>,
5857}
5858
5859impl<T: AstInfo> AstDisplay for CommentStatement<T> {
5860 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5861 f.write_str("COMMENT ON ");
5862 f.write_node(&self.object);
5863
5864 f.write_str(" IS ");
5865 match &self.comment {
5866 Some(s) => {
5867 if f.redacted() {
5868 f.write_str("'<REDACTED>'");
5871 } else {
5872 f.write_str("'");
5873 f.write_node(&display::escape_single_quote_string(s));
5874 f.write_str("'");
5875 }
5876 }
5877 None => f.write_str("NULL"),
5878 }
5879 }
5880}
5881impl_display_t!(CommentStatement);
5882
5883#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
5884pub struct ColumnName<T: AstInfo> {
5885 pub relation: T::ItemName,
5886 pub column: T::ColumnReference,
5887}
5888
5889impl<T: AstInfo> AstDisplay for ColumnName<T> {
5890 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5891 f.write_node(&self.relation);
5892 f.write_str(".");
5893 f.write_node(&self.column);
5894 }
5895}
5896impl_display_t!(ColumnName);
5897
5898#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5899pub enum CommentObjectType<T: AstInfo> {
5900 Table { name: T::ItemName },
5901 View { name: T::ItemName },
5902 Column { name: ColumnName<T> },
5903 MaterializedView { name: T::ItemName },
5904 Source { name: T::ItemName },
5905 Sink { name: T::ItemName },
5906 Index { name: T::ItemName },
5907 Func { name: T::ItemName },
5908 Connection { name: T::ItemName },
5909 Type { ty: T::DataType },
5910 Secret { name: T::ItemName },
5911 Role { name: T::RoleName },
5912 Database { name: T::DatabaseName },
5913 Schema { name: T::SchemaName },
5914 Cluster { name: T::ClusterName },
5915 ClusterReplica { name: QualifiedReplica },
5916 NetworkPolicy { name: T::NetworkPolicyName },
5917}
5918
5919impl<T: AstInfo> AstDisplay for CommentObjectType<T> {
5920 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
5921 use CommentObjectType::*;
5922
5923 match self {
5924 Table { name } => {
5925 f.write_str("TABLE ");
5926 f.write_node(name);
5927 }
5928 View { name } => {
5929 f.write_str("VIEW ");
5930 f.write_node(name);
5931 }
5932 Column { name } => {
5933 f.write_str("COLUMN ");
5934 f.write_node(name);
5935 }
5936 MaterializedView { name } => {
5937 f.write_str("MATERIALIZED VIEW ");
5938 f.write_node(name);
5939 }
5940 Source { name } => {
5941 f.write_str("SOURCE ");
5942 f.write_node(name);
5943 }
5944 Sink { name } => {
5945 f.write_str("SINK ");
5946 f.write_node(name);
5947 }
5948 Index { name } => {
5949 f.write_str("INDEX ");
5950 f.write_node(name);
5951 }
5952 Func { name } => {
5953 f.write_str("FUNCTION ");
5954 f.write_node(name);
5955 }
5956 Connection { name } => {
5957 f.write_str("CONNECTION ");
5958 f.write_node(name);
5959 }
5960 Type { ty } => {
5961 f.write_str("TYPE ");
5962 f.write_node(ty);
5963 }
5964 Secret { name } => {
5965 f.write_str("SECRET ");
5966 f.write_node(name);
5967 }
5968 Role { name } => {
5969 f.write_str("ROLE ");
5970 f.write_node(name);
5971 }
5972 Database { name } => {
5973 f.write_str("DATABASE ");
5974 f.write_node(name);
5975 }
5976 Schema { name } => {
5977 f.write_str("SCHEMA ");
5978 f.write_node(name);
5979 }
5980 Cluster { name } => {
5981 f.write_str("CLUSTER ");
5982 f.write_node(name);
5983 }
5984 ClusterReplica { name } => {
5985 f.write_str("CLUSTER REPLICA ");
5986 f.write_node(name);
5987 }
5988 NetworkPolicy { name } => {
5989 f.write_str("NETWORK POLICY ");
5990 f.write_node(name);
5991 }
5992 }
5993 }
5994}
5995
5996impl_display_t!(CommentObjectType);
5997
5998include!(concat!(env!("OUT_DIR"), "/display.simple_options.rs"));