2020use crate :: ast:: {
2121 display_comma_separated, display_separated, ConstraintCharacteristics ,
2222 ConstraintReferenceMatchKind , Expr , Ident , IndexColumn , IndexOption , IndexType ,
23- KeyOrIndexDisplay , NullsDistinctOption , ObjectName , ReferentialAction ,
23+ KeyOrIndexDisplay , NullsDistinctOption , ObjectName , OrderByOptions , ReferentialAction ,
2424} ;
2525use crate :: tokenizer:: Span ;
2626use core:: fmt;
2727
2828#[ cfg( not( feature = "std" ) ) ]
29- use alloc:: { boxed:: Box , vec:: Vec } ;
29+ use alloc:: { boxed:: Box , string :: String , vec:: Vec } ;
3030
3131#[ cfg( feature = "serde" ) ]
3232use serde:: { Deserialize , Serialize } ;
@@ -619,7 +619,7 @@ impl crate::ast::Spanned for ConstraintUsingIndex {
619619
620620/// One element in an `EXCLUDE` constraint's element list.
621621///
622- /// `<expr> WITH <operator>`
622+ /// `{ column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] WITH <operator>`
623623///
624624/// See <https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE>
625625#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
@@ -628,20 +628,32 @@ impl crate::ast::Spanned for ConstraintUsingIndex {
628628pub struct ExclusionElement {
629629 /// The index expression or column name.
630630 pub expr : Expr ,
631- /// The exclusion operator (e.g. `&&`, `<->`, `=`).
631+ /// Optional operator class (e.g. `gist_geometry_ops_nd`).
632+ pub operator_class : Option < ObjectName > ,
633+ /// Ordering options (ASC/DESC, NULLS FIRST/LAST).
634+ pub order : OrderByOptions ,
635+ /// The exclusion operator. Either a simple token (`&&`, `=`, `<->`) or the
636+ /// Postgres schema-qualified form `OPERATOR(schema.op)`.
632637 pub operator : String ,
633638}
634639
635640impl fmt:: Display for ExclusionElement {
636641 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
637- write ! ( f, "{} WITH {}" , self . expr, self . operator)
642+ write ! ( f, "{}" , self . expr) ?;
643+ if let Some ( opclass) = & self . operator_class {
644+ write ! ( f, " {opclass}" ) ?;
645+ }
646+ write ! ( f, "{} WITH {}" , self . order, self . operator)
638647 }
639648}
640649
641650impl crate :: ast:: Spanned for ExclusionElement {
642651 fn span ( & self ) -> Span {
643- // Operator is stored as a plain String with no source span; only expr contributes.
644- self . expr . span ( )
652+ let mut span = self . expr . span ( ) ;
653+ if let Some ( opclass) = & self . operator_class {
654+ span = span. union ( & opclass. span ( ) ) ;
655+ }
656+ span
645657 }
646658}
647659
@@ -691,11 +703,7 @@ impl fmt::Display for ExclusionConstraint {
691703
692704impl crate :: ast:: Spanned for ExclusionConstraint {
693705 fn span ( & self ) -> Span {
694- fn union_spans < I : Iterator < Item = Span > > ( iter : I ) -> Span {
695- Span :: union_iter ( iter)
696- }
697-
698- union_spans (
706+ Span :: union_iter (
699707 self . name
700708 . iter ( )
701709 . map ( |i| i. span )
0 commit comments