databend_common_ast/ast/statements/
statement.rs

1// Copyright 2021 Datafuse Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Display;
16use std::fmt::Formatter;
17
18use derive_visitor::Drive;
19use derive_visitor::DriveMut;
20use dictionary::CreateDictionaryStmt;
21use dictionary::DropDictionaryStmt;
22use dictionary::ShowCreateDictionaryStmt;
23use itertools::Itertools;
24
25use super::merge_into::MergeIntoStmt;
26use super::*;
27use crate::ast::quote::QuotedString;
28use crate::ast::statements::connection::CreateConnectionStmt;
29use crate::ast::statements::pipe::CreatePipeStmt;
30use crate::ast::statements::settings::Settings;
31use crate::ast::statements::task::CreateTaskStmt;
32use crate::ast::statements::warehouse::ShowWarehousesStmt;
33use crate::ast::statements::workload::CreateWorkloadGroupStmt;
34use crate::ast::statements::workload::DropWorkloadGroupStmt;
35use crate::ast::statements::workload::RenameWorkloadGroupStmt;
36use crate::ast::statements::workload::SetWorkloadGroupQuotasStmt;
37use crate::ast::statements::workload::ShowWorkloadGroupsStmt;
38use crate::ast::write_comma_separated_list;
39use crate::ast::CreateOption;
40use crate::ast::Identifier;
41use crate::ast::Query;
42use crate::Span;
43
44// SQL statement
45#[allow(clippy::large_enum_variant)]
46#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
47pub enum Statement {
48    Query(Box<Query>),
49    StatementWithSettings {
50        settings: Option<Settings>,
51        stmt: Box<Statement>,
52    },
53    Explain {
54        kind: ExplainKind,
55        options: (Span, Vec<ExplainOption>),
56        query: Box<Statement>,
57    },
58    ExplainAnalyze {
59        // if partial is true, only scan/filter/join will be shown.
60        partial: bool,
61        graphical: bool,
62        query: Box<Statement>,
63    },
64    ReportIssue(String),
65
66    CopyIntoTable(CopyIntoTableStmt),
67    CopyIntoLocation(CopyIntoLocationStmt),
68
69    Call(CallStmt),
70
71    ShowSettings {
72        show_options: Option<ShowOptions>,
73    },
74    ShowProcessList {
75        show_options: Option<ShowOptions>,
76    },
77    ShowMetrics {
78        show_options: Option<ShowOptions>,
79    },
80    ShowEngines {
81        show_options: Option<ShowOptions>,
82    },
83    ShowFunctions {
84        show_options: Option<ShowOptions>,
85    },
86    ShowUserFunctions {
87        show_options: Option<ShowOptions>,
88    },
89    ShowTableFunctions {
90        show_options: Option<ShowOptions>,
91    },
92    ShowIndexes {
93        show_options: Option<ShowOptions>,
94    },
95    ShowLocks(ShowLocksStmt),
96
97    KillStmt {
98        kill_target: KillTarget,
99        object_id: String,
100    },
101
102    SetStmt {
103        settings: Settings,
104    },
105    UnSetStmt {
106        settings: Settings,
107    },
108
109    ShowVariables {
110        show_options: Option<ShowOptions>,
111    },
112
113    SetRole {
114        is_default: bool,
115        role_name: String,
116    },
117
118    SetSecondaryRoles {
119        option: SecondaryRolesOption,
120    },
121
122    Insert(InsertStmt),
123    InsertMultiTable(InsertMultiTableStmt),
124    Replace(ReplaceStmt),
125    MergeInto(MergeIntoStmt),
126    Delete(DeleteStmt),
127
128    Update(UpdateStmt),
129
130    // Catalogs
131    ShowCatalogs(ShowCatalogsStmt),
132    ShowCreateCatalog(ShowCreateCatalogStmt),
133    CreateCatalog(CreateCatalogStmt),
134    DropCatalog(DropCatalogStmt),
135    UseCatalog {
136        catalog: Identifier,
137    },
138
139    // Warehouses
140    ShowOnlineNodes(ShowOnlineNodesStmt),
141    UseWarehouse(UseWarehouseStmt),
142    ShowWarehouses(ShowWarehousesStmt),
143    DropWarehouse(DropWarehouseStmt),
144    CreateWarehouse(CreateWarehouseStmt),
145    RenameWarehouse(RenameWarehouseStmt),
146    ResumeWarehouse(ResumeWarehouseStmt),
147    SuspendWarehouse(SuspendWarehouseStmt),
148    InspectWarehouse(InspectWarehouseStmt),
149    AddWarehouseCluster(AddWarehouseClusterStmt),
150    DropWarehouseCluster(DropWarehouseClusterStmt),
151    RenameWarehouseCluster(RenameWarehouseClusterStmt),
152    AssignWarehouseNodes(AssignWarehouseNodesStmt),
153    UnassignWarehouseNodes(UnassignWarehouseNodesStmt),
154
155    // Workloads
156    ShowWorkloadGroups(ShowWorkloadGroupsStmt),
157    CreateWorkloadGroup(CreateWorkloadGroupStmt),
158    DropWorkloadGroup(DropWorkloadGroupStmt),
159    RenameWorkloadGroup(RenameWorkloadGroupStmt),
160    SetWorkloadQuotasGroup(SetWorkloadGroupQuotasStmt),
161    UnsetWorkloadQuotasGroup(UnsetWorkloadGroupQuotasStmt),
162
163    // Databases
164    ShowDatabases(ShowDatabasesStmt),
165    ShowDropDatabases(ShowDropDatabasesStmt),
166    ShowCreateDatabase(ShowCreateDatabaseStmt),
167    CreateDatabase(CreateDatabaseStmt),
168    DropDatabase(DropDatabaseStmt),
169    UndropDatabase(UndropDatabaseStmt),
170    AlterDatabase(AlterDatabaseStmt),
171    UseDatabase {
172        database: Identifier,
173    },
174
175    // Tables
176    ShowTables(ShowTablesStmt),
177    ShowCreateTable(ShowCreateTableStmt),
178    DescribeTable(DescribeTableStmt),
179    ShowTablesStatus(ShowTablesStatusStmt),
180    ShowDropTables(ShowDropTablesStmt),
181    AttachTable(AttachTableStmt),
182    CreateTable(CreateTableStmt),
183    DropTable(DropTableStmt),
184    UndropTable(UndropTableStmt),
185    AlterTable(AlterTableStmt),
186    RenameTable(RenameTableStmt),
187    TruncateTable(TruncateTableStmt),
188    OptimizeTable(OptimizeTableStmt),
189    VacuumTable(VacuumTableStmt),
190    VacuumDropTable(VacuumDropTableStmt),
191    VacuumTemporaryFiles(VacuumTemporaryFiles),
192    AnalyzeTable(AnalyzeTableStmt),
193    ExistsTable(ExistsTableStmt),
194
195    // Dictionaries
196    CreateDictionary(CreateDictionaryStmt),
197    DropDictionary(DropDictionaryStmt),
198    ShowCreateDictionary(ShowCreateDictionaryStmt),
199    ShowDictionaries(ShowDictionariesStmt),
200    RenameDictionary(RenameDictionaryStmt),
201
202    // Columns
203    ShowColumns(ShowColumnsStmt),
204
205    // Views
206    CreateView(CreateViewStmt),
207    AlterView(AlterViewStmt),
208    DropView(DropViewStmt),
209    ShowViews(ShowViewsStmt),
210    DescribeView(DescribeViewStmt),
211
212    // Streams
213    CreateStream(CreateStreamStmt),
214    DropStream(DropStreamStmt),
215    ShowStreams(ShowStreamsStmt),
216    DescribeStream(DescribeStreamStmt),
217
218    // Indexes
219    CreateIndex(CreateIndexStmt),
220    DropIndex(DropIndexStmt),
221    RefreshIndex(RefreshIndexStmt),
222    CreateTableIndex(CreateTableIndexStmt),
223    DropTableIndex(DropTableIndexStmt),
224    RefreshTableIndex(RefreshTableIndexStmt),
225
226    // VirtualColumns
227    RefreshVirtualColumn(RefreshVirtualColumnStmt),
228    ShowVirtualColumns(ShowVirtualColumnsStmt),
229
230    // User
231    ShowUsers {
232        show_options: Option<ShowOptions>,
233    },
234    DescribeUser {
235        user: UserIdentity,
236    },
237    CreateUser(CreateUserStmt),
238    AlterUser(AlterUserStmt),
239    DropUser {
240        if_exists: bool,
241        user: UserIdentity,
242    },
243    ShowRoles {
244        show_options: Option<ShowOptions>,
245    },
246    CreateRole {
247        if_not_exists: bool,
248        role_name: String,
249    },
250    DropRole {
251        if_exists: bool,
252        role_name: String,
253    },
254    Grant(GrantStmt),
255    ShowGrants {
256        principal: Option<PrincipalIdentity>,
257        show_options: Option<ShowOptions>,
258    },
259    ShowObjectPrivileges(ShowObjectPrivilegesStmt),
260    ShowGrantsOfRole(ShowGranteesOfRoleStmt),
261    Revoke(RevokeStmt),
262
263    // UDF
264    CreateUDF(CreateUDFStmt),
265    DropUDF {
266        if_exists: bool,
267        udf_name: Identifier,
268    },
269    AlterUDF(AlterUDFStmt),
270
271    // Stages
272    CreateStage(CreateStageStmt),
273    ShowStages {
274        show_options: Option<ShowOptions>,
275    },
276    DropStage {
277        if_exists: bool,
278        stage_name: String,
279    },
280    DescribeStage {
281        stage_name: String,
282    },
283    RemoveStage {
284        location: String,
285        pattern: String,
286    },
287    ListStage {
288        location: String,
289        pattern: Option<String>,
290    },
291    // Connection
292    CreateConnection(CreateConnectionStmt),
293    DropConnection(DropConnectionStmt),
294    DescribeConnection(DescribeConnectionStmt),
295    ShowConnections(ShowConnectionsStmt),
296
297    // UserDefinedFileFormat
298    CreateFileFormat {
299        create_option: CreateOption,
300        name: String,
301        file_format_options: FileFormatOptions,
302    },
303    DropFileFormat {
304        if_exists: bool,
305        name: String,
306    },
307    ShowFileFormats,
308    Presign(PresignStmt),
309
310    // data mask
311    CreateDatamaskPolicy(CreateDatamaskPolicyStmt),
312    DropDatamaskPolicy(DropDatamaskPolicyStmt),
313    DescDatamaskPolicy(DescDatamaskPolicyStmt),
314
315    // network policy
316    CreateNetworkPolicy(CreateNetworkPolicyStmt),
317    AlterNetworkPolicy(AlterNetworkPolicyStmt),
318    DropNetworkPolicy(DropNetworkPolicyStmt),
319    DescNetworkPolicy(DescNetworkPolicyStmt),
320    ShowNetworkPolicies,
321
322    // password policy
323    CreatePasswordPolicy(CreatePasswordPolicyStmt),
324    AlterPasswordPolicy(AlterPasswordPolicyStmt),
325    DropPasswordPolicy(DropPasswordPolicyStmt),
326    DescPasswordPolicy(DescPasswordPolicyStmt),
327    ShowPasswordPolicies {
328        show_options: Option<ShowOptions>,
329    },
330
331    // tasks
332    CreateTask(CreateTaskStmt),
333    AlterTask(AlterTaskStmt),
334    ExecuteTask(ExecuteTaskStmt),
335    DescribeTask(DescribeTaskStmt),
336    DropTask(DropTaskStmt),
337    ShowTasks(ShowTasksStmt),
338
339    CreateDynamicTable(CreateDynamicTableStmt),
340
341    // pipes
342    CreatePipe(CreatePipeStmt),
343    DescribePipe(DescribePipeStmt),
344    DropPipe(DropPipeStmt),
345    AlterPipe(AlterPipeStmt),
346
347    // Transactions
348    Begin,
349    Commit,
350    Abort,
351
352    // Notifications
353    CreateNotification(CreateNotificationStmt),
354    AlterNotification(AlterNotificationStmt),
355    DropNotification(DropNotificationStmt),
356    DescribeNotification(DescribeNotificationStmt),
357
358    // Stored procedures
359    ExecuteImmediate(ExecuteImmediateStmt),
360    CreateProcedure(CreateProcedureStmt),
361    DropProcedure(DropProcedureStmt),
362    ShowProcedures {
363        show_options: Option<ShowOptions>,
364    },
365    DescProcedure(DescProcedureStmt),
366    CallProcedure(CallProcedureStmt),
367
368    // Sequence
369    CreateSequence(CreateSequenceStmt),
370    DropSequence(DropSequenceStmt),
371    ShowSequences {
372        show_options: Option<ShowOptions>,
373    },
374    DescSequence {
375        name: Identifier,
376    },
377
378    // Set priority for query
379    SetPriority {
380        priority: Priority,
381        object_id: String,
382    },
383
384    // System actions
385    System(SystemStmt),
386}
387
388impl Statement {
389    pub fn to_mask_sql(&self) -> String {
390        match self {
391            Statement::CopyIntoTable(copy) => {
392                let mut copy_clone = copy.clone();
393
394                if let CopyIntoTableSource::Location(FileLocation::Uri(location)) =
395                    &mut copy_clone.src
396                {
397                    location.connection = location.connection.mask()
398                }
399                format!("{}", Statement::CopyIntoTable(copy_clone))
400            }
401            Statement::CopyIntoLocation(copy) => {
402                let mut copy_clone = copy.clone();
403
404                if let FileLocation::Uri(location) = &mut copy_clone.dst {
405                    location.connection = location.connection.mask()
406                }
407                format!("{}", Statement::CopyIntoLocation(copy_clone))
408            }
409            Statement::CreateStage(stage) => {
410                let mut stage_clone = stage.clone();
411                if let Some(location) = &mut stage_clone.location {
412                    location.connection = location.connection.mask()
413                }
414                format!("{}", Statement::CreateStage(stage_clone))
415            }
416            Statement::AttachTable(attach) => {
417                let mut attach_clone = attach.clone();
418                attach_clone.uri_location.connection = attach_clone.uri_location.connection.mask();
419                format!("{}", Statement::AttachTable(attach_clone))
420            }
421            _ => format!("{}", self),
422        }
423    }
424
425    pub fn allowed_in_multi_statement(&self) -> bool {
426        match self {
427            Statement::Query(..)
428            | Statement::Explain { .. }
429            | Statement::ReportIssue { .. }
430            | Statement::ExplainAnalyze { .. }
431            | Statement::CopyIntoTable(..)
432            | Statement::CopyIntoLocation(..)
433            | Statement::Call(..)
434            | Statement::ShowSettings { .. }
435            | Statement::ShowProcessList { .. }
436            | Statement::ShowMetrics { .. }
437            | Statement::ShowEngines { .. }
438            | Statement::ShowFunctions { .. }
439            | Statement::ShowUserFunctions { .. }
440            | Statement::ShowTableFunctions { .. }
441            | Statement::ShowIndexes { .. }
442            | Statement::ShowLocks(..)
443            | Statement::SetPriority { .. }
444            | Statement::System(..)
445            | Statement::KillStmt { .. }
446            | Statement::SetStmt { .. }
447            | Statement::UnSetStmt { .. }
448            | Statement::ShowVariables { .. }
449            | Statement::SetRole { .. }
450            | Statement::SetSecondaryRoles { .. }
451            | Statement::Insert(..)
452            | Statement::InsertMultiTable(..)
453            | Statement::Replace(..)
454            | Statement::MergeInto(..)
455            | Statement::Delete(..)
456            | Statement::Update(..)
457            | Statement::ShowCatalogs(..)
458            | Statement::ShowCreateCatalog(..)
459            | Statement::UseCatalog { .. }
460            | Statement::ShowDatabases(..)
461            | Statement::ShowDropDatabases(..)
462            | Statement::ShowCreateDatabase(..)
463            | Statement::UseDatabase { .. }
464            | Statement::ShowTables(..)
465            | Statement::ShowCreateTable(..)
466            | Statement::DescribeTable(..)
467            | Statement::ShowTablesStatus(..)
468            | Statement::ShowDropTables(..)
469            | Statement::OptimizeTable(..)
470            | Statement::VacuumTable(..)
471            | Statement::VacuumDropTable(..)
472            | Statement::VacuumTemporaryFiles(..)
473            | Statement::AnalyzeTable(..)
474            | Statement::ExistsTable(..)
475            | Statement::ShowCreateDictionary(..)
476            | Statement::ShowDictionaries(..)
477            | Statement::ShowColumns(..)
478            | Statement::ShowViews(..)
479            | Statement::DescribeView(..)
480            | Statement::ShowStreams(..)
481            | Statement::DescribeStream(..)
482            | Statement::RefreshIndex(..)
483            | Statement::RefreshTableIndex(..)
484            | Statement::RefreshVirtualColumn(..)
485            | Statement::ShowVirtualColumns(..)
486            | Statement::ShowUsers { .. }
487            | Statement::DescribeUser { .. }
488            | Statement::ShowRoles { .. }
489            | Statement::ShowGrants { .. }
490            | Statement::ShowObjectPrivileges(..)
491            | Statement::ShowGrantsOfRole(..)
492            | Statement::ShowStages { .. }
493            | Statement::DescribeStage { .. }
494            | Statement::RemoveStage { .. }
495            | Statement::ListStage { .. }
496            | Statement::DescribeConnection(..)
497            | Statement::ShowConnections(..)
498            | Statement::ShowFileFormats
499            | Statement::Presign(..)
500            | Statement::DescDatamaskPolicy(..)
501            | Statement::DescNetworkPolicy(..)
502            | Statement::ShowNetworkPolicies
503            | Statement::DescPasswordPolicy(..)
504            | Statement::ShowPasswordPolicies { .. }
505            | Statement::ExecuteTask(..)
506            | Statement::DescribeTask(..)
507            | Statement::ShowTasks(..)
508            | Statement::DescribePipe(..)
509            | Statement::Begin
510            | Statement::Commit
511            | Statement::Abort
512            | Statement::DescribeNotification(..)
513            | Statement::ExecuteImmediate(..)
514            | Statement::ShowProcedures { .. }
515            | Statement::ShowSequences { .. }
516            | Statement::DescSequence { .. }
517            | Statement::DescProcedure(..)
518            | Statement::CallProcedure(..)
519            | Statement::ShowWarehouses(..)
520            | Statement::ShowOnlineNodes(..)
521            | Statement::InspectWarehouse(..) => true,
522
523            Statement::CreateDatabase(..)
524            | Statement::CreateTable(..)
525            | Statement::CreateView(..)
526            | Statement::CreateIndex(..)
527            | Statement::CreateStage(..)
528            | Statement::CreateSequence(..)
529            | Statement::CreateDictionary(..)
530            | Statement::CreateConnection(..)
531            | Statement::CreatePipe(..)
532            | Statement::AlterTable(..)
533            | Statement::AlterView(..)
534            | Statement::AlterUser(..)
535            | Statement::AlterDatabase(..)
536            | Statement::DropDatabase(..)
537            | Statement::DropTable(..)
538            | Statement::DropView(..)
539            | Statement::DropIndex(..)
540            | Statement::DropSequence(..)
541            | Statement::DropDictionary(..)
542            | Statement::TruncateTable(..)
543            | Statement::AttachTable(..)
544            | Statement::RenameTable(..)
545            | Statement::CreateCatalog(..)
546            | Statement::DropCatalog(..)
547            | Statement::UndropDatabase(..)
548            | Statement::UndropTable(..)
549            | Statement::RenameDictionary(..)
550            | Statement::CreateStream(..)
551            | Statement::DropStream(..)
552            | Statement::CreateTableIndex(..)
553            | Statement::DropTableIndex(..)
554            | Statement::CreateUser(..)
555            | Statement::DropUser { .. }
556            | Statement::CreateRole { .. }
557            | Statement::DropRole { .. }
558            | Statement::Grant(..)
559            | Statement::Revoke(..)
560            | Statement::CreateUDF(..)
561            | Statement::DropUDF { .. }
562            | Statement::AlterUDF(..)
563            | Statement::DropStage { .. }
564            | Statement::DropConnection(..)
565            | Statement::CreateFileFormat { .. }
566            | Statement::DropFileFormat { .. }
567            | Statement::CreateDatamaskPolicy(..)
568            | Statement::DropDatamaskPolicy(..)
569            | Statement::CreateNetworkPolicy(..)
570            | Statement::AlterNetworkPolicy(..)
571            | Statement::DropNetworkPolicy(..)
572            | Statement::CreatePasswordPolicy(..)
573            | Statement::AlterPasswordPolicy(..)
574            | Statement::DropPasswordPolicy(..)
575            | Statement::CreateTask(..)
576            | Statement::AlterTask(..)
577            | Statement::DropTask(..)
578            | Statement::CreateDynamicTable(..)
579            | Statement::DropPipe(..)
580            | Statement::AlterPipe(..)
581            | Statement::CreateNotification(..)
582            | Statement::AlterNotification(..)
583            | Statement::DropNotification(..)
584            | Statement::CreateProcedure(..)
585            | Statement::DropProcedure(..)
586            | Statement::CreateWarehouse(..)
587            | Statement::UseWarehouse(..)
588            | Statement::DropWarehouse(..)
589            | Statement::RenameWarehouse(..)
590            | Statement::AddWarehouseCluster(..)
591            | Statement::DropWarehouseCluster(..)
592            | Statement::RenameWarehouseCluster(..)
593            | Statement::AssignWarehouseNodes(..)
594            | Statement::UnassignWarehouseNodes(..)
595            | Statement::ResumeWarehouse(..)
596            | Statement::SuspendWarehouse(..)
597            | Statement::ShowWorkloadGroups(..)
598            | Statement::CreateWorkloadGroup(..)
599            | Statement::DropWorkloadGroup(..)
600            | Statement::RenameWorkloadGroup(..)
601            | Statement::SetWorkloadQuotasGroup(..)
602            | Statement::UnsetWorkloadQuotasGroup(..) => false,
603            Statement::StatementWithSettings { stmt, settings: _ } => {
604                stmt.allowed_in_multi_statement()
605            }
606        }
607    }
608
609    pub fn is_transaction_command(&self) -> bool {
610        matches!(
611            self,
612            Statement::Commit | Statement::Abort | Statement::Begin
613        )
614    }
615}
616
617impl Display for Statement {
618    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
619        match self {
620            Statement::Explain {
621                options: (_, options),
622                kind,
623                query,
624            } => {
625                write!(f, "EXPLAIN")?;
626                if !options.is_empty() {
627                    write!(
628                        f,
629                        "({})",
630                        options
631                            .iter()
632                            .map(|opt| {
633                                match opt {
634                                    ExplainOption::Verbose => "VERBOSE",
635                                    ExplainOption::Logical => "LOGICAL",
636                                    ExplainOption::Optimized => "OPTIMIZED",
637                                    ExplainOption::Decorrelated => "DECORRELATED",
638                                }
639                            })
640                            .join(", ")
641                    )?;
642                }
643                match *kind {
644                    ExplainKind::Ast(_) => write!(f, " AST")?,
645                    ExplainKind::Syntax(_) => write!(f, " SYNTAX")?,
646                    ExplainKind::Graph => write!(f, " GRAPH")?,
647                    ExplainKind::Pipeline => write!(f, " PIPELINE")?,
648                    ExplainKind::Fragments => write!(f, " FRAGMENTS")?,
649                    ExplainKind::Raw => write!(f, " RAW")?,
650                    ExplainKind::Optimized => write!(f, " Optimized")?,
651                    ExplainKind::Decorrelated => write!(f, " DECORRELATED")?,
652                    ExplainKind::Plan => (),
653                    ExplainKind::AnalyzePlan => write!(f, " ANALYZE")?,
654                    ExplainKind::Join => write!(f, " JOIN")?,
655                    ExplainKind::Memo(_) => write!(f, " MEMO")?,
656                    ExplainKind::Graphical => write!(f, " GRAPHICAL")?,
657                    ExplainKind::Perf => write!(f, " PERF")?,
658                }
659                write!(f, " {query}")?;
660            }
661            Statement::ReportIssue(sql) => {
662                write!(f, "REPORT ISSUE {}", sql)?;
663            }
664            Statement::StatementWithSettings { settings, stmt } => {
665                if let Some(setting) = settings {
666                    write!(f, "SETTINGS (")?;
667                    let ids = &setting.identifiers;
668                    if let SetValues::Expr(values) = &setting.values {
669                        let mut expr = Vec::with_capacity(ids.len());
670                        for (id, value) in ids.iter().zip(values.iter()) {
671                            expr.push(format!("{} = {}", id, value));
672                        }
673                        write_comma_separated_list(f, expr)?;
674                    } else {
675                        unreachable!();
676                    }
677                    write!(f, ") ")?;
678                } else {
679                    write!(f, "SETTINGS ")?;
680                }
681                write!(f, "{stmt}")?;
682            }
683            Statement::ExplainAnalyze {
684                partial,
685                graphical,
686                query,
687            } => {
688                if *partial {
689                    write!(f, "EXPLAIN ANALYZE PARTIAL {query}")?;
690                } else if *graphical {
691                    write!(f, "EXPLAIN ANALYZE GRAPHICAL {query}")?;
692                } else {
693                    write!(f, "EXPLAIN ANALYZE {query}")?;
694                }
695            }
696            Statement::Query(stmt) => write!(f, "{stmt}")?,
697            Statement::Insert(stmt) => write!(f, "{stmt}")?,
698            Statement::InsertMultiTable(insert_multi_table) => write!(f, "{insert_multi_table}")?,
699            Statement::Replace(stmt) => write!(f, "{stmt}")?,
700            Statement::MergeInto(stmt) => write!(f, "{stmt}")?,
701            Statement::Delete(stmt) => write!(f, "{stmt}")?,
702            Statement::Update(stmt) => write!(f, "{stmt}")?,
703            Statement::CopyIntoTable(stmt) => write!(f, "{stmt}")?,
704            Statement::CopyIntoLocation(stmt) => write!(f, "{stmt}")?,
705            Statement::ShowSettings { show_options } => {
706                write!(f, "SHOW SETTINGS")?;
707                if let Some(show_options) = show_options {
708                    write!(f, " {show_options}")?;
709                }
710            }
711            Statement::ShowVariables { show_options } => {
712                write!(f, "SHOW VARIABLES")?;
713                if let Some(show_options) = show_options {
714                    write!(f, " {show_options}")?;
715                }
716            }
717            Statement::ShowProcessList { show_options } => {
718                write!(f, "SHOW PROCESSLIST")?;
719                if let Some(show_options) = show_options {
720                    write!(f, " {show_options}")?;
721                }
722            }
723            Statement::ShowMetrics { show_options } => {
724                write!(f, "SHOW METRICS")?;
725                if let Some(show_options) = show_options {
726                    write!(f, " {show_options}")?;
727                }
728            }
729            Statement::ShowEngines { show_options } => {
730                write!(f, "SHOW ENGINES")?;
731                if let Some(show_options) = show_options {
732                    write!(f, " {show_options}")?;
733                }
734            }
735            Statement::ShowIndexes { show_options } => {
736                write!(f, "SHOW INDEXES")?;
737                if let Some(show_options) = show_options {
738                    write!(f, " {show_options}")?;
739                }
740            }
741            Statement::ShowFunctions { show_options } => {
742                write!(f, "SHOW FUNCTIONS")?;
743                if let Some(show_options) = show_options {
744                    write!(f, " {show_options}")?;
745                }
746            }
747            Statement::ShowUserFunctions { show_options } => {
748                write!(f, "SHOW USER FUNCTIONS")?;
749                if let Some(show_options) = show_options {
750                    write!(f, " {show_options}")?;
751                }
752            }
753            Statement::ShowTableFunctions { show_options } => {
754                write!(f, "SHOW TABLE_FUNCTIONS")?;
755                if let Some(show_options) = show_options {
756                    write!(f, " {show_options}")?;
757                }
758            }
759            Statement::ShowLocks(stmt) => write!(f, "{stmt}")?,
760            Statement::KillStmt {
761                kill_target,
762                object_id,
763            } => {
764                write!(f, "KILL")?;
765                match *kill_target {
766                    KillTarget::Query => write!(f, " QUERY")?,
767                    KillTarget::Connection => write!(f, " CONNECTION")?,
768                }
769                write!(f, " '{object_id}'")?;
770            }
771            Statement::SetStmt { settings } => write!(f, "SET {}", settings)?,
772            Statement::UnSetStmt { settings } => write!(f, "UNSET {}", settings)?,
773            Statement::SetRole {
774                is_default,
775                role_name,
776            } => {
777                write!(f, "SET ")?;
778                if *is_default {
779                    write!(f, "DEFAULT ")?;
780                }
781                write!(f, "ROLE '{role_name}'")?;
782            }
783            Statement::SetSecondaryRoles { option } => {
784                write!(f, "SET SECONDARY ROLES ")?;
785                match option {
786                    SecondaryRolesOption::None => write!(f, "NONE")?,
787                    SecondaryRolesOption::All => write!(f, "ALL")?,
788                    SecondaryRolesOption::SpecifyRole(roles) => {
789                        write_comma_separated_list(f, roles)?
790                    }
791                }
792            }
793            Statement::ShowCatalogs(stmt) => write!(f, "{stmt}")?,
794            Statement::ShowCreateCatalog(stmt) => write!(f, "{stmt}")?,
795            Statement::CreateCatalog(stmt) => write!(f, "{stmt}")?,
796            Statement::DropCatalog(stmt) => write!(f, "{stmt}")?,
797            Statement::UseCatalog { catalog } => write!(f, "USE CATALOG {catalog}")?,
798            Statement::ShowDatabases(stmt) => write!(f, "{stmt}")?,
799            Statement::ShowDropDatabases(stmt) => write!(f, "{stmt}")?,
800            Statement::ShowCreateDatabase(stmt) => write!(f, "{stmt}")?,
801            Statement::CreateDatabase(stmt) => write!(f, "{stmt}")?,
802            Statement::DropDatabase(stmt) => write!(f, "{stmt}")?,
803            Statement::UndropDatabase(stmt) => write!(f, "{stmt}")?,
804            Statement::AlterDatabase(stmt) => write!(f, "{stmt}")?,
805            Statement::UseDatabase { database } => write!(f, "USE {database}")?,
806            Statement::ShowTables(stmt) => write!(f, "{stmt}")?,
807            Statement::ShowColumns(stmt) => write!(f, "{stmt}")?,
808            Statement::ShowCreateTable(stmt) => write!(f, "{stmt}")?,
809            Statement::DescribeTable(stmt) => write!(f, "{stmt}")?,
810            Statement::ShowTablesStatus(stmt) => write!(f, "{stmt}")?,
811            Statement::ShowDropTables(stmt) => write!(f, "{stmt}")?,
812            Statement::AttachTable(stmt) => write!(f, "{stmt}")?,
813            Statement::CreateTable(stmt) => write!(f, "{stmt}")?,
814            Statement::DropTable(stmt) => write!(f, "{stmt}")?,
815            Statement::UndropTable(stmt) => write!(f, "{stmt}")?,
816            Statement::AlterTable(stmt) => write!(f, "{stmt}")?,
817            Statement::RenameTable(stmt) => write!(f, "{stmt}")?,
818            Statement::TruncateTable(stmt) => write!(f, "{stmt}")?,
819            Statement::OptimizeTable(stmt) => write!(f, "{stmt}")?,
820            Statement::VacuumTable(stmt) => write!(f, "{stmt}")?,
821            Statement::VacuumDropTable(stmt) => write!(f, "{stmt}")?,
822            Statement::VacuumTemporaryFiles(stmt) => write!(f, "{stmt}")?,
823            Statement::AnalyzeTable(stmt) => write!(f, "{stmt}")?,
824            Statement::ExistsTable(stmt) => write!(f, "{stmt}")?,
825            Statement::CreateDictionary(stmt) => write!(f, "{stmt}")?,
826            Statement::DropDictionary(stmt) => write!(f, "{stmt}")?,
827            Statement::ShowCreateDictionary(stmt) => write!(f, "{stmt}")?,
828            Statement::ShowDictionaries(stmt) => write!(f, "{stmt}")?,
829            Statement::RenameDictionary(stmt) => write!(f, "{stmt}")?,
830            Statement::CreateView(stmt) => write!(f, "{stmt}")?,
831            Statement::AlterView(stmt) => write!(f, "{stmt}")?,
832            Statement::DropView(stmt) => write!(f, "{stmt}")?,
833            Statement::ShowViews(stmt) => write!(f, "{stmt}")?,
834            Statement::DescribeView(stmt) => write!(f, "{stmt}")?,
835            Statement::CreateStream(stmt) => write!(f, "{stmt}")?,
836            Statement::DropStream(stmt) => write!(f, "{stmt}")?,
837            Statement::ShowStreams(stmt) => write!(f, "{stmt}")?,
838            Statement::DescribeStream(stmt) => write!(f, "{stmt}")?,
839            Statement::CreateIndex(stmt) => write!(f, "{stmt}")?,
840            Statement::DropIndex(stmt) => write!(f, "{stmt}")?,
841            Statement::RefreshIndex(stmt) => write!(f, "{stmt}")?,
842            Statement::CreateTableIndex(stmt) => write!(f, "{stmt}")?,
843            Statement::DropTableIndex(stmt) => write!(f, "{stmt}")?,
844            Statement::RefreshTableIndex(stmt) => write!(f, "{stmt}")?,
845            Statement::RefreshVirtualColumn(stmt) => write!(f, "{stmt}")?,
846            Statement::ShowVirtualColumns(stmt) => write!(f, "{stmt}")?,
847            Statement::ShowUsers { show_options } => {
848                write!(f, "SHOW USERS")?;
849                if let Some(show_options) = show_options {
850                    write!(f, " {show_options}")?;
851                }
852            }
853            Statement::DescribeUser { user } => write!(f, "DESCRIBE USER {user}")?,
854            Statement::ShowRoles { show_options } => {
855                write!(f, "SHOW ROLES")?;
856                if let Some(show_options) = show_options {
857                    write!(f, " {show_options}")?;
858                }
859            }
860            Statement::CreateUser(stmt) => write!(f, "{stmt}")?,
861            Statement::AlterUser(stmt) => write!(f, "{stmt}")?,
862            Statement::DropUser { if_exists, user } => {
863                write!(f, "DROP USER")?;
864                if *if_exists {
865                    write!(f, " IF EXISTS")?;
866                }
867                write!(f, " {}", user)?;
868            }
869            Statement::CreateRole {
870                if_not_exists,
871                role_name: role,
872            } => {
873                write!(f, "CREATE ROLE")?;
874                if *if_not_exists {
875                    write!(f, " IF NOT EXISTS")?;
876                }
877                write!(f, " {}", QuotedString(role, '\''))?;
878            }
879            Statement::DropRole {
880                if_exists,
881                role_name: role,
882            } => {
883                write!(f, "DROP ROLE")?;
884                if *if_exists {
885                    write!(f, " IF EXISTS")?;
886                }
887                write!(f, " '{role}'")?;
888            }
889            Statement::Grant(stmt) => write!(f, "{stmt}")?,
890            Statement::ShowGrants {
891                principal,
892                show_options,
893            } => {
894                write!(f, "SHOW GRANTS")?;
895                if let Some(principal) = principal {
896                    write!(f, " FOR")?;
897                    write!(f, "{principal}")?;
898                }
899                if let Some(show_options) = show_options {
900                    write!(f, " {show_options}")?;
901                }
902            }
903            Statement::ShowObjectPrivileges(stmt) => write!(f, "{stmt}")?,
904            Statement::ShowGrantsOfRole(stmt) => write!(f, "{stmt}")?,
905            Statement::Revoke(stmt) => write!(f, "{stmt}")?,
906            Statement::CreateUDF(stmt) => write!(f, "{stmt}")?,
907            Statement::DropUDF {
908                if_exists,
909                udf_name,
910            } => {
911                write!(f, "DROP FUNCTION")?;
912                if *if_exists {
913                    write!(f, " IF EXISTS")?;
914                }
915                write!(f, " {udf_name}")?;
916            }
917            Statement::AlterUDF(stmt) => write!(f, "{stmt}")?,
918            Statement::ListStage { location, pattern } => {
919                write!(f, "LIST @{location}")?;
920                if let Some(pattern) = pattern {
921                    write!(f, " PATTERN = '{pattern}'")?;
922                }
923            }
924            Statement::ShowStages { show_options } => {
925                write!(f, "SHOW STAGES")?;
926                if let Some(show_options) = show_options {
927                    write!(f, " {show_options}")?;
928                }
929            }
930            Statement::DropStage {
931                if_exists,
932                stage_name,
933            } => {
934                write!(f, "DROP STAGE")?;
935                if *if_exists {
936                    write!(f, " IF EXISTS")?;
937                }
938                write!(f, " {stage_name}")?;
939            }
940            Statement::CreateStage(stmt) => write!(f, "{stmt}")?,
941            Statement::RemoveStage { location, pattern } => {
942                write!(f, "REMOVE @{location}")?;
943                if !pattern.is_empty() {
944                    write!(f, " PATTERN = '{pattern}'")?;
945                }
946            }
947            Statement::DescribeStage { stage_name } => write!(f, "DESC STAGE {stage_name}")?,
948            Statement::CreateFileFormat {
949                create_option,
950                name,
951                file_format_options,
952            } => {
953                write!(f, "CREATE")?;
954                if let CreateOption::CreateOrReplace = create_option {
955                    write!(f, " OR REPLACE")?;
956                }
957                write!(f, " FILE FORMAT")?;
958                if let CreateOption::CreateIfNotExists = create_option {
959                    write!(f, " IF NOT EXISTS")?;
960                }
961                write!(f, " {name}")?;
962                write!(f, " {file_format_options}")?;
963            }
964            Statement::DropFileFormat { if_exists, name } => {
965                write!(f, "DROP FILE FORMAT")?;
966                if *if_exists {
967                    write!(f, " IF EXISTS")?;
968                }
969                write!(f, " {name}")?;
970            }
971            Statement::ShowFileFormats => write!(f, "SHOW FILE FORMATS")?,
972            Statement::Call(stmt) => write!(f, "{stmt}")?,
973            Statement::Presign(stmt) => write!(f, "{stmt}")?,
974            Statement::CreateDatamaskPolicy(stmt) => write!(f, "{stmt}")?,
975            Statement::DropDatamaskPolicy(stmt) => write!(f, "{stmt}")?,
976            Statement::DescDatamaskPolicy(stmt) => write!(f, "{stmt}")?,
977            Statement::CreateNetworkPolicy(stmt) => write!(f, "{stmt}")?,
978            Statement::AlterNetworkPolicy(stmt) => write!(f, "{stmt}")?,
979            Statement::DropNetworkPolicy(stmt) => write!(f, "{stmt}")?,
980            Statement::DescNetworkPolicy(stmt) => write!(f, "{stmt}")?,
981            Statement::ShowNetworkPolicies => write!(f, "SHOW NETWORK POLICIES")?,
982            Statement::CreatePasswordPolicy(stmt) => write!(f, "{stmt}")?,
983            Statement::AlterPasswordPolicy(stmt) => write!(f, "{stmt}")?,
984            Statement::DropPasswordPolicy(stmt) => write!(f, "{stmt}")?,
985            Statement::DescPasswordPolicy(stmt) => write!(f, "{stmt}")?,
986            Statement::ShowPasswordPolicies { show_options } => {
987                write!(f, "SHOW PASSWORD POLICIES")?;
988                if let Some(show_options) = show_options {
989                    write!(f, " {show_options}")?;
990                }
991            }
992            Statement::CreateTask(stmt) => write!(f, "{stmt}")?,
993            Statement::AlterTask(stmt) => write!(f, "{stmt}")?,
994            Statement::ExecuteTask(stmt) => write!(f, "{stmt}")?,
995            Statement::DropTask(stmt) => write!(f, "{stmt}")?,
996            Statement::ShowTasks(stmt) => write!(f, "{stmt}")?,
997            Statement::DescribeTask(stmt) => write!(f, "{stmt}")?,
998            Statement::CreatePipe(stmt) => write!(f, "{stmt}")?,
999            Statement::DescribePipe(stmt) => write!(f, "{stmt}")?,
1000            Statement::DropPipe(stmt) => write!(f, "{stmt}")?,
1001            Statement::AlterPipe(stmt) => write!(f, "{stmt}")?,
1002            Statement::CreateConnection(stmt) => write!(f, "{stmt}")?,
1003            Statement::DropConnection(stmt) => write!(f, "{stmt}")?,
1004            Statement::DescribeConnection(stmt) => write!(f, "{stmt}")?,
1005            Statement::ShowConnections(stmt) => write!(f, "{stmt}")?,
1006            Statement::Begin => write!(f, "BEGIN")?,
1007            Statement::Commit => write!(f, "COMMIT")?,
1008            Statement::Abort => write!(f, "ABORT")?,
1009            Statement::CreateNotification(stmt) => write!(f, "{stmt}")?,
1010            Statement::AlterNotification(stmt) => write!(f, "{stmt}")?,
1011            Statement::DropNotification(stmt) => write!(f, "{stmt}")?,
1012            Statement::DescribeNotification(stmt) => write!(f, "{stmt}")?,
1013            Statement::ExecuteImmediate(stmt) => write!(f, "{stmt}")?,
1014            Statement::CreateProcedure(stmt) => write!(f, "{stmt}")?,
1015            Statement::DropProcedure(stmt) => write!(f, "{stmt}")?,
1016            Statement::DescProcedure(stmt) => write!(f, "{stmt}")?,
1017            Statement::ShowProcedures { show_options } => {
1018                write!(f, "SHOW PROCEDURES")?;
1019                if let Some(show_options) = show_options {
1020                    write!(f, " {show_options}")?;
1021                }
1022            }
1023            Statement::CreateSequence(stmt) => write!(f, "{stmt}")?,
1024            Statement::DropSequence(stmt) => write!(f, "{stmt}")?,
1025            Statement::ShowSequences { show_options } => {
1026                write!(f, "SHOW SEQUENCES")?;
1027                if let Some(show_options) = show_options {
1028                    write!(f, " {show_options}")?;
1029                }
1030            }
1031            Statement::DescSequence { name } => {
1032                write!(f, "DESC SEQUENCE {name}")?;
1033            }
1034            Statement::CreateDynamicTable(stmt) => write!(f, "{stmt}")?,
1035            Statement::SetPriority {
1036                priority,
1037                object_id,
1038            } => {
1039                write!(f, "SET PRIORITY")?;
1040                write!(f, " {priority}")?;
1041                write!(f, " '{object_id}'")?;
1042            }
1043            Statement::System(stmt) => write!(f, "{stmt}")?,
1044            Statement::CallProcedure(stmt) => write!(f, "{stmt}")?,
1045
1046            Statement::ShowOnlineNodes(stmt) => write!(f, "{stmt}")?,
1047            Statement::ShowWarehouses(stmt) => write!(f, "{stmt}")?,
1048            Statement::UseWarehouse(stmt) => write!(f, "{stmt}")?,
1049            Statement::DropWarehouse(stmt) => write!(f, "{stmt}")?,
1050            Statement::CreateWarehouse(stmt) => write!(f, "{stmt}")?,
1051            Statement::RenameWarehouse(stmt) => write!(f, "{stmt}")?,
1052            Statement::ResumeWarehouse(stmt) => write!(f, "{stmt}")?,
1053            Statement::SuspendWarehouse(stmt) => write!(f, "{stmt}")?,
1054            Statement::InspectWarehouse(stmt) => write!(f, "{stmt}")?,
1055            Statement::AddWarehouseCluster(stmt) => write!(f, "{stmt}")?,
1056            Statement::DropWarehouseCluster(stmt) => write!(f, "{stmt}")?,
1057            Statement::RenameWarehouseCluster(stmt) => write!(f, "{stmt}")?,
1058            Statement::AssignWarehouseNodes(stmt) => write!(f, "{stmt}")?,
1059            Statement::UnassignWarehouseNodes(stmt) => write!(f, "{stmt}")?,
1060            Statement::ShowWorkloadGroups(stmt) => write!(f, "{stmt}")?,
1061            Statement::CreateWorkloadGroup(stmt) => write!(f, "{stmt}")?,
1062            Statement::DropWorkloadGroup(stmt) => write!(f, "{stmt}")?,
1063            Statement::RenameWorkloadGroup(stmt) => write!(f, "{stmt}")?,
1064            Statement::SetWorkloadQuotasGroup(stmt) => write!(f, "{stmt}")?,
1065            Statement::UnsetWorkloadQuotasGroup(stmt) => write!(f, "{stmt}")?,
1066        }
1067        Ok(())
1068    }
1069}
1070
1071#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1072pub struct StatementWithFormat {
1073    pub(crate) stmt: Statement,
1074    pub(crate) format: Option<String>,
1075}
1076
1077impl Display for StatementWithFormat {
1078    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1079        write!(f, "{}", self.stmt)?;
1080        if let Some(format) = &self.format {
1081            write!(f, " FORMAT {}", format)?;
1082        }
1083        Ok(())
1084    }
1085}