@@ -40,8 +40,14 @@ use serde::{Deserialize, Serialize};
4040#[ cfg( feature = "visitor" ) ]
4141use sqlparser_derive:: { Visit , VisitMut } ;
4242
43- use crate :: keywords:: Keyword ;
44- use crate :: tokenizer:: { Span , Token } ;
43+ use crate :: {
44+ display_utils:: SpaceOrNewline ,
45+ tokenizer:: { Span , Token } ,
46+ } ;
47+ use crate :: {
48+ display_utils:: { Indent , NewLine } ,
49+ keywords:: Keyword ,
50+ } ;
4551
4652pub use self :: data_type:: {
4753 ArrayElemTypeDef , BinaryLength , CharLengthUnits , CharacterLength , DataType , EnumMember ,
@@ -134,9 +140,9 @@ where
134140 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
135141 let mut delim = "" ;
136142 for t in self . slice {
137- write ! ( f , "{ delim}" ) ?;
143+ f . write_str ( delim) ?;
138144 delim = self . sep ;
139- write ! ( f , "{t}" ) ?;
145+ t . fmt ( f ) ?;
140146 }
141147 Ok ( ( ) )
142148 }
@@ -628,7 +634,12 @@ pub struct CaseWhen {
628634
629635impl fmt:: Display for CaseWhen {
630636 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
631- write ! ( f, "WHEN {} THEN {}" , self . condition, self . result)
637+ f. write_str ( "WHEN " ) ?;
638+ self . condition . fmt ( f) ?;
639+ f. write_str ( " THEN" ) ?;
640+ SpaceOrNewline . fmt ( f) ?;
641+ Indent ( & self . result ) . fmt ( f) ?;
642+ Ok ( ( ) )
632643 }
633644}
634645
@@ -1662,23 +1673,29 @@ impl fmt::Display for Expr {
16621673 write ! ( f, "{data_type}" ) ?;
16631674 write ! ( f, " {value}" )
16641675 }
1665- Expr :: Function ( fun) => write ! ( f , "{fun}" ) ,
1676+ Expr :: Function ( fun) => fun . fmt ( f ) ,
16661677 Expr :: Case {
16671678 operand,
16681679 conditions,
16691680 else_result,
16701681 } => {
1671- write ! ( f , "CASE" ) ?;
1682+ f . write_str ( "CASE" ) ?;
16721683 if let Some ( operand) = operand {
1673- write ! ( f, " {operand}" ) ?;
1684+ f. write_str ( " " ) ?;
1685+ operand. fmt ( f) ?;
16741686 }
16751687 for when in conditions {
1676- write ! ( f, " {when}" ) ?;
1688+ SpaceOrNewline . fmt ( f) ?;
1689+ Indent ( when) . fmt ( f) ?;
16771690 }
16781691 if let Some ( else_result) = else_result {
1679- write ! ( f, " ELSE {else_result}" ) ?;
1692+ SpaceOrNewline . fmt ( f) ?;
1693+ Indent ( "ELSE" ) . fmt ( f) ?;
1694+ SpaceOrNewline . fmt ( f) ?;
1695+ Indent ( Indent ( else_result) ) . fmt ( f) ?;
16801696 }
1681- write ! ( f, " END" )
1697+ SpaceOrNewline . fmt ( f) ?;
1698+ f. write_str ( "END" )
16821699 }
16831700 Expr :: Exists { subquery, negated } => write ! (
16841701 f,
@@ -1867,8 +1884,14 @@ pub enum WindowType {
18671884impl Display for WindowType {
18681885 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
18691886 match self {
1870- WindowType :: WindowSpec ( spec) => write ! ( f, "({})" , spec) ,
1871- WindowType :: NamedWindow ( name) => write ! ( f, "{}" , name) ,
1887+ WindowType :: WindowSpec ( spec) => {
1888+ f. write_str ( "(" ) ?;
1889+ NewLine . fmt ( f) ?;
1890+ Indent ( spec) . fmt ( f) ?;
1891+ NewLine . fmt ( f) ?;
1892+ f. write_str ( ")" )
1893+ }
1894+ WindowType :: NamedWindow ( name) => name. fmt ( f) ,
18721895 }
18731896 }
18741897}
@@ -1896,27 +1919,36 @@ pub struct WindowSpec {
18961919
18971920impl fmt:: Display for WindowSpec {
18981921 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1899- let mut delim = "" ;
1922+ let mut is_first = true ;
19001923 if let Some ( window_name) = & self . window_name {
1901- delim = " " ;
1924+ if !is_first {
1925+ SpaceOrNewline . fmt ( f) ?;
1926+ }
1927+ is_first = false ;
19021928 write ! ( f, "{window_name}" ) ?;
19031929 }
19041930 if !self . partition_by . is_empty ( ) {
1905- f. write_str ( delim) ?;
1906- delim = " " ;
1931+ if !is_first {
1932+ SpaceOrNewline . fmt ( f) ?;
1933+ }
1934+ is_first = false ;
19071935 write ! (
19081936 f,
19091937 "PARTITION BY {}" ,
19101938 display_comma_separated( & self . partition_by)
19111939 ) ?;
19121940 }
19131941 if !self . order_by . is_empty ( ) {
1914- f. write_str ( delim) ?;
1915- delim = " " ;
1942+ if !is_first {
1943+ SpaceOrNewline . fmt ( f) ?;
1944+ }
1945+ is_first = false ;
19161946 write ! ( f, "ORDER BY {}" , display_comma_separated( & self . order_by) ) ?;
19171947 }
19181948 if let Some ( window_frame) = & self . window_frame {
1919- f. write_str ( delim) ?;
1949+ if !is_first {
1950+ SpaceOrNewline . fmt ( f) ?;
1951+ }
19201952 if let Some ( end_bound) = & window_frame. end_bound {
19211953 write ! (
19221954 f,
@@ -4204,6 +4236,28 @@ impl fmt::Display for RaisErrorOption {
42044236}
42054237
42064238impl fmt:: Display for Statement {
4239+ /// Formats a SQL statement with support for pretty printing.
4240+ ///
4241+ /// When using the alternate flag (`{:#}`), the statement will be formatted with proper
4242+ /// indentation and line breaks. For example:
4243+ ///
4244+ /// ```
4245+ /// # use sqlparser::dialect::GenericDialect;
4246+ /// # use sqlparser::parser::Parser;
4247+ /// let sql = "SELECT a, b FROM table_1";
4248+ /// let ast = Parser::parse_sql(&GenericDialect, sql).unwrap();
4249+ ///
4250+ /// // Regular formatting
4251+ /// assert_eq!(format!("{}", ast[0]), "SELECT a, b FROM table_1");
4252+ ///
4253+ /// // Pretty printing
4254+ /// assert_eq!(format!("{:#}", ast[0]),
4255+ /// r#"SELECT
4256+ /// a,
4257+ /// b
4258+ /// FROM
4259+ /// table_1"#);
4260+ /// ```
42074261 // Clippy thinks this function is too complicated, but it is painful to
42084262 // split up without extracting structs for each `Statement` variant.
42094263 #[ allow( clippy:: cognitive_complexity) ]
@@ -4219,7 +4273,8 @@ impl fmt::Display for Statement {
42194273 } => {
42204274 write ! ( f, "FLUSH" ) ?;
42214275 if let Some ( location) = location {
4222- write ! ( f, " {location}" ) ?;
4276+ f. write_str ( " " ) ?;
4277+ location. fmt ( f) ?;
42234278 }
42244279 write ! ( f, " {object_type}" ) ?;
42254280
@@ -4301,7 +4356,7 @@ impl fmt::Display for Statement {
43014356
43024357 write ! ( f, "{statement}" )
43034358 }
4304- Statement :: Query ( s) => write ! ( f , "{s}" ) ,
4359+ Statement :: Query ( s) => s . fmt ( f ) ,
43054360 Statement :: Declare { stmts } => {
43064361 write ! ( f, "DECLARE " ) ?;
43074362 write ! ( f, "{}" , display_separated( stmts, "; " ) )
@@ -7056,7 +7111,8 @@ impl fmt::Display for Function {
70567111 }
70577112
70587113 if let Some ( o) = & self . over {
7059- write ! ( f, " OVER {o}" ) ?;
7114+ f. write_str ( " OVER " ) ?;
7115+ o. fmt ( f) ?;
70607116 }
70617117
70627118 if self . uses_odbc_syntax {
0 commit comments