@@ -477,6 +477,22 @@ pub enum CastKind {
477477 DoubleColon ,
478478}
479479
480+ /// `EXTRACT` syntax variants.
481+ ///
482+ /// In Snowflake dialect, the `EXTRACT` expression can support either the `from` syntax
483+ /// or the comma syntax.
484+ ///
485+ /// See <https://docs.snowflake.com/en/sql-reference/functions/extract>
486+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
487+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
488+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
489+ pub enum ExtractSyntax {
490+ /// `EXTRACT( <date_or_time_part> FROM <date_or_time_expr> )`
491+ From ,
492+ /// `EXTRACT( <date_or_time_part> , <date_or_timestamp_expr> )`
493+ Comma ,
494+ }
495+
480496/// An SQL expression of any type.
481497///
482498/// The parser does not distinguish between expressions of different types
@@ -637,13 +653,15 @@ pub enum Expr {
637653 time_zone : Box < Expr > ,
638654 } ,
639655 /// Extract a field from a timestamp e.g. `EXTRACT(MONTH FROM foo)`
656+ /// Or `EXTRACT(MONTH, foo)`
640657 ///
641658 /// Syntax:
642659 /// ```sql
643- /// EXTRACT(DateTimeField FROM <expr>)
660+ /// EXTRACT(DateTimeField FROM <expr>) | EXTRACT(DateTimeField, <expr>)
644661 /// ```
645662 Extract {
646663 field : DateTimeField ,
664+ syntax : ExtractSyntax ,
647665 expr : Box < Expr > ,
648666 } ,
649667 /// ```sql
@@ -1197,7 +1215,14 @@ impl fmt::Display for Expr {
11971215 write ! ( f, "{expr}::{data_type}" )
11981216 }
11991217 } ,
1200- Expr :: Extract { field, expr } => write ! ( f, "EXTRACT({field} FROM {expr})" ) ,
1218+ Expr :: Extract {
1219+ field,
1220+ syntax,
1221+ expr,
1222+ } => match syntax {
1223+ ExtractSyntax :: From => write ! ( f, "EXTRACT({field} FROM {expr})" ) ,
1224+ ExtractSyntax :: Comma => write ! ( f, "EXTRACT({field}, {expr})" ) ,
1225+ } ,
12011226 Expr :: Ceil { expr, field } => {
12021227 if field == & DateTimeField :: NoDateTime {
12031228 write ! ( f, "CEIL({expr})" )
0 commit comments