iffyio commented on code in PR #1884:
URL: 
https://github.com/apache/datafusion-sqlparser-rs/pull/1884#discussion_r2149643500


##########
src/ast/mod.rs:
##########
@@ -2982,6 +2982,63 @@ impl From<Set> for Statement {
     }
 }
 
+/// An exception representing exception handling with the `EXCEPTION` keyword.
+///
+/// Snowflake: 
<https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
+/// BigQuery: 
<https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct Exception {

Review Comment:
   ```suggestion
   pub struct ExceptionClause {
   ```



##########
src/ast/mod.rs:
##########
@@ -2982,6 +2982,63 @@ impl From<Set> for Statement {
     }
 }
 
+/// An exception representing exception handling with the `EXCEPTION` keyword.
+///
+/// Snowflake: 
<https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
+/// BigQuery: 
<https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct Exception {
+    pub when: Vec<ExceptionWhen>,
+    pub raises: Option<Box<Statement>>,

Review Comment:
   Can we add a description what raises refers to here? thinking since its 
being represetned as a box statement it won't be obvious



##########
src/ast/mod.rs:
##########
@@ -2982,6 +2982,63 @@ impl From<Set> for Statement {
     }
 }
 
+/// An exception representing exception handling with the `EXCEPTION` keyword.
+///
+/// Snowflake: 
<https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
+/// BigQuery: 
<https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct Exception {
+    pub when: Vec<ExceptionWhen>,
+    pub raises: Option<Box<Statement>>,
+}
+
+impl Display for Exception {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, " EXCEPTION")?;
+        for w in &self.when {
+            write!(f, "{w}")?;
+        }
+
+        if let Some(raises) = &self.raises {
+            write!(f, " {raises};")?;
+        }
+
+        Ok(())
+    }
+}
+
+/// A representation of a `WHEN` arm with all the identifiers catched and the 
statements to execute
+/// for the arm.
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct ExceptionWhen {
+    pub idents: Vec<Ident>,
+    pub statements: Vec<Statement>,
+}
+
+impl Display for ExceptionWhen {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let idents = self
+            .idents
+            .iter()
+            .map(ToString::to_string)
+            .collect::<Vec<_>>()
+            .join(" OR ");
+
+        write!(f, " WHEN {idents} THEN", idents = idents)?;

Review Comment:
   ```suggestion
           write!(f, " WHEN {idents} THEN")?;
   ```



##########
src/parser/mod.rs:
##########
@@ -15096,12 +15096,16 @@ impl<'a> Parser<'a> {
             transaction: Some(BeginTransactionKind::Transaction),
             modifier: None,
             statements: vec![],
-            exception_statements: None,
+            exception: None,
             has_end_keyword: false,
         })
     }
 
     pub fn parse_begin(&mut self) -> Result<Statement, ParserError> {
+        if dialect_of!(self is SnowflakeDialect | BigQueryDialect) {

Review Comment:
   the `dialect_of` macro is discouraged for new code, for dialect-specific 
functionality we would use a method on the Dialect trait - but I don't think 
that would work too well in this case, I think we can use the previous pattern 
of having the dialect call the method instead (i.e the parse_statement approach)



##########
src/ast/mod.rs:
##########
@@ -3670,17 +3727,24 @@ pub enum Statement {
         /// END;
         /// ```
         statements: Vec<Statement>,
-        /// Statements of an exception clause.
+        /// Exception handling with exception clauses and raises.
         /// Example:
         /// ```sql
         /// BEGIN
         ///     SELECT 1;
-        /// EXCEPTION WHEN ERROR THEN
-        ///     SELECT 2;
-        ///     SELECT 3;
+        /// EXCEPTION
+        ///     WHEN EXCEPTION_1 THEN
+        ///         SELECT 2;
+        ///     WHEN EXCEPTION_2 OR EXCEPTION_3 THEN
+        ///         SELECT 3;
+        ///     WHEN OTHER THEN
+        ///         SELECT 4;
+        /// RAISE;

Review Comment:
   given the syntax example, Im not sure I see the requirement for the 
introduced `Exception` struct - here the `RAISE` looks like a normal statement 
that belongs either to the `EXCEPTION` clause, or the `BEGIN` statement itself? 
If the former, could it be represented as another statement in the 
`Vec<Statement>`?, if the latter seems like its out of place in the new 
`Exception` struct?



##########
tests/sqlparser_common.rs:
##########
@@ -8593,7 +8593,7 @@ fn lateral_function() {
 fn parse_start_transaction() {
     let dialects = all_dialects_except(|d|
         // BigQuery does not support this syntax
-        d.is::<BigQueryDialect>());
+        d.is::<BigQueryDialect>() || d.is::<SnowflakeDialect>());

Review Comment:
   the comment above becomes outdated by this change, we should probably adjust 
it to be generic or mention sf



##########
src/ast/mod.rs:
##########
@@ -2982,6 +2982,63 @@ impl From<Set> for Statement {
     }
 }
 
+/// An exception representing exception handling with the `EXCEPTION` keyword.
+///
+/// Snowflake: 
<https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
+/// BigQuery: 
<https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct Exception {
+    pub when: Vec<ExceptionWhen>,
+    pub raises: Option<Box<Statement>>,
+}
+
+impl Display for Exception {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, " EXCEPTION")?;
+        for w in &self.when {
+            write!(f, "{w}")?;
+        }
+
+        if let Some(raises) = &self.raises {
+            write!(f, " {raises};")?;
+        }
+
+        Ok(())
+    }
+}
+
+/// A representation of a `WHEN` arm with all the identifiers catched and the 
statements to execute
+/// for the arm.

Review Comment:
   Can we add a link to the docs here as well?



##########
src/ast/mod.rs:
##########
@@ -2982,6 +2982,63 @@ impl From<Set> for Statement {
     }
 }
 
+/// An exception representing exception handling with the `EXCEPTION` keyword.
+///
+/// Snowflake: 
<https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
+/// BigQuery: 
<https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct Exception {
+    pub when: Vec<ExceptionWhen>,
+    pub raises: Option<Box<Statement>>,
+}
+
+impl Display for Exception {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, " EXCEPTION")?;
+        for w in &self.when {
+            write!(f, "{w}")?;
+        }
+
+        if let Some(raises) = &self.raises {
+            write!(f, " {raises};")?;
+        }
+
+        Ok(())
+    }
+}
+
+/// A representation of a `WHEN` arm with all the identifiers catched and the 
statements to execute
+/// for the arm.
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct ExceptionWhen {
+    pub idents: Vec<Ident>,
+    pub statements: Vec<Statement>,
+}
+
+impl Display for ExceptionWhen {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let idents = self
+            .idents
+            .iter()
+            .map(ToString::to_string)
+            .collect::<Vec<_>>()
+            .join(" OR ");

Review Comment:
   Can this use 
[display_separated](https://github.com/apache/datafusion-sqlparser-rs/blob/f69e0d928c2ee6a72261a3dace68228d7ad79e96/src/ast/mod.rs#L151)?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org
For additional commands, e-mail: github-h...@datafusion.apache.org

Reply via email to