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