fmguerreiro commented on code in PR #2307:
URL: 
https://github.com/apache/datafusion-sqlparser-rs/pull/2307#discussion_r3140755108


##########
src/ast/table_constraints.rs:
##########
@@ -117,6 +117,12 @@ pub enum TableConstraint {
     ///
     /// [1]: https://www.postgresql.org/docs/current/sql-altertable.html
     UniqueUsingIndex(ConstraintUsingIndex),
+    /// PostgreSQL `EXCLUDE` constraint.
+    ///
+    /// `[ CONSTRAINT <name> ] EXCLUDE [ USING <index_method> ] ( <element> 
WITH <operator> [, ...] ) [ INCLUDE (<cols>) ] [ WHERE (<predicate>) ]`
+    ///
+    /// See 
<https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE>
+    Exclusion(ExclusionConstraint),

Review Comment:
   renamed in 60b5fd2.



##########
src/ast/table_constraints.rs:
##########
@@ -117,6 +117,12 @@ pub enum TableConstraint {
     ///
     /// [1]: https://www.postgresql.org/docs/current/sql-altertable.html
     UniqueUsingIndex(ConstraintUsingIndex),
+    /// PostgreSQL `EXCLUDE` constraint.
+    ///
+    /// `[ CONSTRAINT <name> ] EXCLUDE [ USING <index_method> ] ( <element> 
WITH <operator> [, ...] ) [ INCLUDE (<cols>) ] [ WHERE (<predicate>) ]`
+    ///
+    /// See 
<https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE>

Review Comment:
   updated in 60b5fd2.



##########
src/ast/table_constraints.rs:
##########
@@ -603,3 +616,123 @@ impl crate::ast::Spanned for ConstraintUsingIndex {
         start.union(&end)
     }
 }
+
+/// The operator that follows `WITH` in an `EXCLUDE` element.
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub enum ExclusionOperator {
+    /// A single operator token, e.g. `=`, `&&`, `<->`.
+    Token(String),
+    /// Postgres schema-qualified form: `OPERATOR(schema.op)`.
+    PgCustom(Vec<String>),
+}
+
+impl fmt::Display for ExclusionOperator {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            ExclusionOperator::Token(token) => f.write_str(token),
+            ExclusionOperator::PgCustom(parts) => {
+                write!(f, "OPERATOR({})", display_separated(parts, "."))
+            }
+        }
+    }
+}
+
+/// One element in an `EXCLUDE` constraint's element list.
+///
+/// `{ column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { 
FIRST | LAST } ] WITH <operator>`
+///
+/// See 
<https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE>

Review Comment:
   updated in 60b5fd2.



##########
src/ast/table_constraints.rs:
##########
@@ -603,3 +616,123 @@ impl crate::ast::Spanned for ConstraintUsingIndex {
         start.union(&end)
     }
 }
+
+/// The operator that follows `WITH` in an `EXCLUDE` element.
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub enum ExclusionOperator {

Review Comment:
   renamed in 60b5fd2.



##########
src/ast/table_constraints.rs:
##########
@@ -603,3 +616,123 @@ impl crate::ast::Spanned for ConstraintUsingIndex {
         start.union(&end)
     }
 }
+
+/// The operator that follows `WITH` in an `EXCLUDE` element.

Review Comment:
   doc link added in 60b5fd2.



##########
src/ast/table_constraints.rs:
##########
@@ -603,3 +616,123 @@ impl crate::ast::Spanned for ConstraintUsingIndex {
         start.union(&end)
     }
 }
+
+/// The operator that follows `WITH` in an `EXCLUDE` element.
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub enum ExclusionOperator {
+    /// A single operator token, e.g. `=`, `&&`, `<->`.
+    Token(String),
+    /// Postgres schema-qualified form: `OPERATOR(schema.op)`.
+    PgCustom(Vec<String>),
+}
+
+impl fmt::Display for ExclusionOperator {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            ExclusionOperator::Token(token) => f.write_str(token),
+            ExclusionOperator::PgCustom(parts) => {
+                write!(f, "OPERATOR({})", display_separated(parts, "."))
+            }
+        }
+    }
+}
+
+/// One element in an `EXCLUDE` constraint's element list.
+///
+/// `{ column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { 
FIRST | LAST } ] WITH <operator>`
+///
+/// See 
<https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct ExclusionElement {

Review Comment:
   renamed in 60b5fd2.



##########
src/ast/table_constraints.rs:
##########
@@ -603,3 +616,123 @@ impl crate::ast::Spanned for ConstraintUsingIndex {
         start.union(&end)
     }
 }
+
+/// The operator that follows `WITH` in an `EXCLUDE` element.
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub enum ExclusionOperator {
+    /// A single operator token, e.g. `=`, `&&`, `<->`.
+    Token(String),
+    /// Postgres schema-qualified form: `OPERATOR(schema.op)`.
+    PgCustom(Vec<String>),
+}
+
+impl fmt::Display for ExclusionOperator {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            ExclusionOperator::Token(token) => f.write_str(token),
+            ExclusionOperator::PgCustom(parts) => {
+                write!(f, "OPERATOR({})", display_separated(parts, "."))
+            }
+        }
+    }
+}
+
+/// One element in an `EXCLUDE` constraint's element list.
+///
+/// `{ column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { 
FIRST | LAST } ] WITH <operator>`
+///
+/// See 
<https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct ExclusionElement {
+    /// The index expression or column name.
+    pub expr: Expr,
+    /// Optional operator class (e.g. `gist_geometry_ops_nd`).
+    pub operator_class: Option<ObjectName>,
+    /// Ordering options (ASC/DESC, NULLS FIRST/LAST).
+    pub order: OrderByOptions,
+    /// The exclusion operator.
+    pub operator: ExclusionOperator,
+}
+
+impl fmt::Display for ExclusionElement {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.expr)?;
+        if let Some(opclass) = &self.operator_class {
+            write!(f, " {opclass}")?;
+        }
+        write!(f, "{} WITH {}", self.order, self.operator)
+    }
+}
+
+impl crate::ast::Spanned for ExclusionElement {
+    fn span(&self) -> Span {
+        let mut span = self.expr.span();
+        if let Some(opclass) = &self.operator_class {
+            span = span.union(&opclass.span());
+        }
+        span
+    }
+}
+
+/// A PostgreSQL `EXCLUDE` constraint.
+///
+/// `[ CONSTRAINT <name> ] EXCLUDE [ USING <index_method> ] ( <element> WITH 
<operator> [, ...] ) [ INCLUDE (<cols>) ] [ WHERE (<predicate>) ]`
+///
+/// See 
<https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE>

Review Comment:
   updated in 60b5fd2.



##########
src/parser/mod.rs:
##########
@@ -508,10 +508,10 @@ impl<'a> Parser<'a> {
                 Token::EOF => break,
 
                 // end of statement
-                Token::Word(word) => {
-                    if expecting_statement_delimiter && word.keyword == 
Keyword::END {
-                        break;
-                    }
+                Token::Word(word)
+                    if expecting_statement_delimiter && word.keyword == 
Keyword::END =>

Review Comment:
   merged main in fc8b794, unrelated diff dropped in 60b5fd2.



##########
src/parser/mod.rs:
##########
@@ -9915,9 +9895,55 @@ impl<'a> Parser<'a> {
                     .into(),
                 ))
             }
+            Token::Word(w)
+                if w.keyword == Keyword::EXCLUDE
+                    && dialect_of!(self is PostgreSqlDialect | GenericDialect) 
=>

Review Comment:
   added `Dialect::supports_exclude_constraint()` in 60b5fd2 (default `false`, 
true for `PostgreSqlDialect` and `GenericDialect`). macro guard replaced with 
the new method.



##########
src/parser/mod.rs:
##########
@@ -9915,9 +9895,55 @@ impl<'a> Parser<'a> {
                     .into(),
                 ))
             }
+            Token::Word(w)
+                if w.keyword == Keyword::EXCLUDE
+                    && dialect_of!(self is PostgreSqlDialect | GenericDialect) 
=>
+            {
+                let index_method = if self.parse_keyword(Keyword::USING) {

Review Comment:
   extracted into `parse_exclude_constraint` in 60b5fd2.



##########
src/parser/mod.rs:
##########
@@ -9926,6 +9952,71 @@ impl<'a> Parser<'a> {
         }
     }
 
+    fn parse_exclusion_element(&mut self) -> Result<ExclusionElement, 
ParserError> {
+        // `index_elem` grammar: { col | (expr) } [ opclass ] [ ASC | DESC ] [ 
NULLS FIRST | LAST ].

Review Comment:
   done in 60b5fd2.



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to