@@ -2790,32 +2790,57 @@ impl fmt::Display for WhileStatement {
27902790#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
27912791#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
27922792pub struct ForStatement {
2793- /// Loop counter variable.
2793+ /// Loop counter (range form) or row variable (cursor form) .
27942794 pub var : Ident ,
2795- /// `true` when the loop iterates from `end` down to `start`.
2796- pub reverse : bool ,
2797- /// Inclusive lower bound (or upper bound when `reverse`).
2798- pub start : Expr ,
2799- /// Inclusive upper bound (or lower bound when `reverse`).
2800- pub end : Expr ,
2795+ /// What the loop iterates over.
2796+ pub iteration : ForIterationSource ,
28012797 /// Loop body statements.
28022798 pub body : ConditionalStatements ,
28032799}
28042800
2801+ /// The thing a [`ForStatement`] iterates over.
2802+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2803+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2804+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2805+ pub enum ForIterationSource {
2806+ /// Numeric range: `[REVERSE] <start> TO <end>`.
2807+ Range {
2808+ /// `true` when the loop iterates from `end` down to `start`.
2809+ reverse : bool ,
2810+ /// Inclusive lower bound (or upper bound when `reverse`).
2811+ start : Expr ,
2812+ /// Inclusive upper bound (or lower bound when `reverse`).
2813+ end : Expr ,
2814+ } ,
2815+ /// Iterate over a cursor or query result set: `FOR row IN cursor DO`.
2816+ ///
2817+ /// [Snowflake](https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors)
2818+ Cursor ( Expr ) ,
2819+ }
2820+
28052821impl fmt:: Display for ForStatement {
28062822 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
28072823 let ForStatement {
28082824 var,
2809- reverse,
2810- start,
2811- end,
2825+ iteration,
28122826 body,
28132827 } = self ;
28142828 write ! ( f, "FOR {var} IN " ) ?;
2815- if * reverse {
2816- write ! ( f, "REVERSE " ) ?;
2829+ match iteration {
2830+ ForIterationSource :: Range {
2831+ reverse,
2832+ start,
2833+ end,
2834+ } => {
2835+ if * reverse {
2836+ write ! ( f, "REVERSE " ) ?;
2837+ }
2838+ write ! ( f, "{start} TO {end} DO" ) ?;
2839+ }
2840+ ForIterationSource :: Cursor ( source) => {
2841+ write ! ( f, "{source} DO" ) ?;
2842+ }
28172843 }
2818- write ! ( f, "{start} TO {end} DO" ) ?;
28192844 if !body. statements ( ) . is_empty ( ) {
28202845 write ! ( f, " {body}" ) ?;
28212846 }
0 commit comments