@@ -2122,8 +2122,8 @@ pub struct CaseStatement {
21222122 /// The `CASE` token that starts the statement.
21232123 pub case_token : AttachedToken ,
21242124 pub match_expr : Option < Expr > ,
2125- pub when_blocks : Vec < ConditionalStatements > ,
2126- pub else_block : Option < ConditionalStatements > ,
2125+ pub when_blocks : Vec < ConditionalStatementBlock > ,
2126+ pub else_block : Option < ConditionalStatementBlock > ,
21272127 /// The last token of the statement (`END` or `CASE`).
21282128 pub end_case_token : AttachedToken ,
21292129}
@@ -2165,127 +2165,60 @@ impl fmt::Display for CaseStatement {
21652165}
21662166
21672167/// An `IF` statement.
2168+ ///
2169+ /// Example (BigQuery or Snowflake):
2170+ /// ```sql
2171+ /// IF TRUE THEN
2172+ /// SELECT 1;
2173+ /// SELECT 2;
2174+ /// ELSEIF TRUE THEN
2175+ /// SELECT 3;
2176+ /// ELSE
2177+ /// SELECT 4;
2178+ /// END IF
2179+ /// ```
2180+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#if)
2181+ /// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/if)
2182+ ///
2183+ /// Example (MSSQL):
2184+ /// ```sql
2185+ /// IF 1=1 SELECT 1 ELSE SELECT 2
2186+ /// ```
2187+ /// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-ver16)
21682188#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
21692189#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
21702190#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2171- pub enum IfStatement {
2172- /// An `IF ... THEN [ELSE[IF] ...] END IF` statement.
2173- ///
2174- /// Example:
2175- /// ```sql
2176- /// IF TRUE THEN
2177- /// SELECT 1;
2178- /// SELECT 2;
2179- /// ELSEIF TRUE THEN
2180- /// SELECT 3;
2181- /// ELSE
2182- /// SELECT 4;
2183- /// END IF
2184- /// ```
2185- ///
2186- /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#if)
2187- /// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/if)
2188- IfThenElseEnd {
2189- /// The `IF` token that starts the statement.
2190- if_token : AttachedToken ,
2191- if_block : ConditionalStatements ,
2192- elseif_blocks : Vec < ConditionalStatements > ,
2193- else_block : Option < ConditionalStatements > ,
2194- /// The `IF` token that ends the statement.
2195- end_if_token : AttachedToken ,
2196- } ,
2197- /// An MSSQL `IF ... ELSE ...` statement.
2198- ///
2199- /// Example:
2200- /// ```sql
2201- /// IF 1=1 SELECT 1 ELSE SELECT 2
2202- /// ```
2203- ///
2204- /// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-ver16)
2205- MsSqlIfElse {
2206- if_token : AttachedToken ,
2207- condition : Expr ,
2208- if_statements : MsSqlIfStatements ,
2209- else_statements : Option < MsSqlIfStatements > ,
2210- } ,
2191+ pub struct IfStatement {
2192+ pub if_block : ConditionalStatementBlock ,
2193+ pub elseif_blocks : Vec < ConditionalStatementBlock > ,
2194+ pub else_block : Option < ConditionalStatementBlock > ,
2195+ pub end_token : Option < AttachedToken > ,
22112196}
22122197
22132198impl fmt:: Display for IfStatement {
22142199 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2215- match self {
2216- IfStatement :: IfThenElseEnd {
2217- if_token : _,
2218- if_block,
2219- elseif_blocks,
2220- else_block,
2221- end_if_token : _,
2222- } => {
2223- write ! ( f, "{if_block}" ) ?;
2224-
2225- if !elseif_blocks. is_empty ( ) {
2226- write ! ( f, " {}" , display_separated( elseif_blocks, " " ) ) ?;
2227- }
2228-
2229- if let Some ( else_block) = else_block {
2230- write ! ( f, " {else_block}" ) ?;
2231- }
2232-
2233- write ! ( f, " END IF" ) ?;
2234-
2235- Ok ( ( ) )
2236- }
2237- IfStatement :: MsSqlIfElse {
2238- if_token : _,
2239- condition,
2240- if_statements,
2241- else_statements,
2242- } => {
2243- write ! ( f, "IF {condition} {if_statements}" ) ?;
2200+ let IfStatement {
2201+ if_block,
2202+ elseif_blocks,
2203+ else_block,
2204+ end_token,
2205+ } = self ;
22442206
2245- if let Some ( els) = else_statements {
2246- write ! ( f, " ELSE {els}" ) ?;
2247- }
2207+ write ! ( f, "{if_block}" ) ?;
22482208
2249- Ok ( ( ) )
2250- }
2209+ for elseif_block in elseif_blocks {
2210+ write ! ( f , " {elseif_block}" ) ? ;
22512211 }
2252- }
2253- }
22542212
2255- /// (MSSQL) Either a single [Statement] or a block of statements
2256- /// enclosed in `BEGIN` and `END`.
2257- #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2258- #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2259- #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2260- pub enum MsSqlIfStatements {
2261- /// A single statement.
2262- Single ( Box < Statement > ) ,
2263- /// ```sql
2264- /// A logical block of statements.
2265- ///
2266- /// BEGIN
2267- /// <statement>;
2268- /// <statement>;
2269- /// ...
2270- /// END
2271- /// ```
2272- Block {
2273- begin_token : AttachedToken ,
2274- statements : Vec < Statement > ,
2275- end_token : AttachedToken ,
2276- } ,
2277- }
2213+ if let Some ( else_block) = else_block {
2214+ write ! ( f, " {else_block}" ) ?;
2215+ }
22782216
2279- impl fmt:: Display for MsSqlIfStatements {
2280- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2281- match self {
2282- MsSqlIfStatements :: Single ( stmt) => stmt. fmt ( f) ,
2283- MsSqlIfStatements :: Block { statements, .. } => {
2284- write ! ( f, "BEGIN " ) ?;
2285- format_statement_list ( f, statements) ?;
2286- write ! ( f, " END" )
2287- }
2217+ if let Some ( AttachedToken ( end_token) ) = end_token {
2218+ write ! ( f, " END {end_token}" ) ?;
22882219 }
2220+
2221+ Ok ( ( ) )
22892222 }
22902223}
22912224
@@ -2308,40 +2241,88 @@ impl fmt::Display for MsSqlIfStatements {
23082241#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
23092242#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
23102243#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2311- pub struct ConditionalStatements {
2312- /// The start token of the conditional (`WHEN`, `IF`, `ELSEIF` or `ELSE`).
2244+ pub struct ConditionalStatementBlock {
23132245 pub start_token : AttachedToken ,
2314- /// The condition expression. `None` for `ELSE` statements.
23152246 pub condition : Option < Expr > ,
2316- /// Statement list of the `THEN` clause.
2317- pub statements : Vec < Statement > ,
2247+ pub then_token : Option < AttachedToken > ,
2248+ pub conditional_statements : ConditionalStatements ,
23182249}
23192250
2320- impl fmt:: Display for ConditionalStatements {
2251+ impl ConditionalStatementBlock {
2252+ pub fn statements ( & self ) -> & Vec < Statement > {
2253+ self . conditional_statements . statements ( )
2254+ }
2255+ }
2256+
2257+ impl fmt:: Display for ConditionalStatementBlock {
23212258 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2322- let ConditionalStatements {
2323- start_token : AttachedToken ( start ) ,
2259+ let ConditionalStatementBlock {
2260+ start_token : AttachedToken ( start_token ) ,
23242261 condition,
2325- statements,
2262+ then_token,
2263+ conditional_statements,
23262264 } = self ;
23272265
2328- let keyword = & start . token ;
2266+ write ! ( f , "{start_token}" ) ? ;
23292267
2330- if let Some ( expr) = condition {
2331- write ! ( f, "{keyword} {expr} THEN" ) ?;
2332- } else {
2333- write ! ( f, "{keyword}" ) ?;
2268+ if let Some ( condition) = condition {
2269+ write ! ( f, " {condition}" ) ?;
2270+ }
2271+
2272+ if then_token. is_some ( ) {
2273+ write ! ( f, " THEN" ) ?;
23342274 }
23352275
2336- if !statements. is_empty ( ) {
2337- write ! ( f, " " ) ?;
2338- format_statement_list ( f, statements) ?;
2276+ if conditional_statements. statements ( ) . len ( ) > 0 {
2277+ write ! ( f, " {conditional_statements}" ) ?;
23392278 }
23402279
23412280 Ok ( ( ) )
23422281 }
23432282}
23442283
2284+ /// A list of statements in a [ConditionalStatementBlock].
2285+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2286+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2287+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2288+ pub enum ConditionalStatements {
2289+ /// SELECT 1; SELECT 2; SELECT 3; ...
2290+ Sequence { statements : Vec < Statement > } ,
2291+ /// BEGIN SELECT 1; SELECT 2; SELECT 3; ... END
2292+ BeginEnd {
2293+ begin_token : AttachedToken ,
2294+ statements : Vec < Statement > ,
2295+ end_token : AttachedToken ,
2296+ } ,
2297+ }
2298+
2299+ impl ConditionalStatements {
2300+ pub fn statements ( & self ) -> & Vec < Statement > {
2301+ match self {
2302+ ConditionalStatements :: Sequence { statements } => statements,
2303+ ConditionalStatements :: BeginEnd { statements, .. } => statements,
2304+ }
2305+ }
2306+ }
2307+
2308+ impl fmt:: Display for ConditionalStatements {
2309+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2310+ match self {
2311+ ConditionalStatements :: Sequence { statements } => {
2312+ if statements. len ( ) > 0 {
2313+ format_statement_list ( f, statements) ?;
2314+ }
2315+ Ok ( ( ) )
2316+ }
2317+ ConditionalStatements :: BeginEnd { statements, .. } => {
2318+ write ! ( f, "BEGIN " ) ?;
2319+ format_statement_list ( f, statements) ?;
2320+ write ! ( f, " END" )
2321+ }
2322+ }
2323+ }
2324+ }
2325+
23452326/// A `RAISE` statement.
23462327///
23472328/// Examples:
0 commit comments