@@ -9134,6 +9134,51 @@ fn parse_pg_analyze() {
91349134 }
91359135}
91369136
9137+ #[ test]
9138+ fn parse_exclude_constraint_basic ( ) {
9139+ let sql =
9140+ "CREATE TABLE t (room INT, CONSTRAINT no_overlap EXCLUDE USING gist (room WITH =))" ;
9141+ match pg ( ) . verified_stmt ( sql) {
9142+ Statement :: CreateTable ( create_table) => {
9143+ assert_eq ! ( 1 , create_table. constraints. len( ) ) ;
9144+ match & create_table. constraints [ 0 ] {
9145+ TableConstraint :: Exclusion ( c) => {
9146+ assert_eq ! ( c. name, Some ( Ident :: new( "no_overlap" ) ) ) ;
9147+ assert_eq ! ( c. index_method, Some ( Ident :: new( "gist" ) ) ) ;
9148+ assert_eq ! ( c. elements. len( ) , 1 ) ;
9149+ assert_eq ! ( c. elements[ 0 ] . operator, "=" ) ;
9150+ assert_eq ! ( c. include. len( ) , 0 ) ;
9151+ assert ! ( c. where_clause. is_none( ) ) ;
9152+ }
9153+ other => panic ! ( "Expected Exclusion, got {other:?}" ) ,
9154+ }
9155+ }
9156+ _ => panic ! ( "Expected CreateTable" ) ,
9157+ }
9158+ }
9159+
9160+ #[ test]
9161+ fn parse_exclude_constraint_multi_element ( ) {
9162+ let sql =
9163+ "CREATE TABLE t (room INT, during INT, EXCLUDE USING gist (room WITH =, during WITH &&))" ;
9164+ match pg ( ) . verified_stmt ( sql) {
9165+ Statement :: CreateTable ( create_table) => {
9166+ assert_eq ! ( 1 , create_table. constraints. len( ) ) ;
9167+ match & create_table. constraints [ 0 ] {
9168+ TableConstraint :: Exclusion ( c) => {
9169+ assert ! ( c. name. is_none( ) ) ;
9170+ assert_eq ! ( c. index_method, Some ( Ident :: new( "gist" ) ) ) ;
9171+ assert_eq ! ( c. elements. len( ) , 2 ) ;
9172+ assert_eq ! ( c. elements[ 0 ] . operator, "=" ) ;
9173+ assert_eq ! ( c. elements[ 1 ] . operator, "&&" ) ;
9174+ }
9175+ other => panic ! ( "Expected Exclusion, got {other:?}" ) ,
9176+ }
9177+ }
9178+ _ => panic ! ( "Expected CreateTable" ) ,
9179+ }
9180+ }
9181+
91379182#[ test]
91389183fn parse_lock_table ( ) {
91399184 pg_and_generic ( ) . one_statement_parses_to (
@@ -9193,3 +9238,92 @@ fn parse_lock_table() {
91939238 }
91949239 }
91959240}
9241+
9242+ #[ test]
9243+ fn parse_exclude_constraint_with_where ( ) {
9244+ let sql =
9245+ "CREATE TABLE t (col INT, EXCLUDE USING gist (col WITH =) WHERE (col > 0))" ;
9246+ match pg ( ) . verified_stmt ( sql) {
9247+ Statement :: CreateTable ( create_table) => {
9248+ assert_eq ! ( 1 , create_table. constraints. len( ) ) ;
9249+ match & create_table. constraints [ 0 ] {
9250+ TableConstraint :: Exclusion ( c) => {
9251+ assert ! ( c. where_clause. is_some( ) ) ;
9252+ }
9253+ other => panic ! ( "Expected Exclusion, got {other:?}" ) ,
9254+ }
9255+ }
9256+ _ => panic ! ( "Expected CreateTable" ) ,
9257+ }
9258+ }
9259+
9260+ #[ test]
9261+ fn parse_exclude_constraint_with_include ( ) {
9262+ let sql =
9263+ "CREATE TABLE t (col INT, EXCLUDE USING gist (col WITH =) INCLUDE (col))" ;
9264+ match pg ( ) . verified_stmt ( sql) {
9265+ Statement :: CreateTable ( create_table) => {
9266+ assert_eq ! ( 1 , create_table. constraints. len( ) ) ;
9267+ match & create_table. constraints [ 0 ] {
9268+ TableConstraint :: Exclusion ( c) => {
9269+ assert_eq ! ( c. include, vec![ Ident :: new( "col" ) ] ) ;
9270+ }
9271+ other => panic ! ( "Expected Exclusion, got {other:?}" ) ,
9272+ }
9273+ }
9274+ _ => panic ! ( "Expected CreateTable" ) ,
9275+ }
9276+ }
9277+
9278+ #[ test]
9279+ fn parse_exclude_constraint_no_using ( ) {
9280+ let sql = "CREATE TABLE t (col INT, EXCLUDE (col WITH =))" ;
9281+ match pg ( ) . verified_stmt ( sql) {
9282+ Statement :: CreateTable ( create_table) => {
9283+ assert_eq ! ( 1 , create_table. constraints. len( ) ) ;
9284+ match & create_table. constraints [ 0 ] {
9285+ TableConstraint :: Exclusion ( c) => {
9286+ assert ! ( c. index_method. is_none( ) ) ;
9287+ }
9288+ other => panic ! ( "Expected Exclusion, got {other:?}" ) ,
9289+ }
9290+ }
9291+ _ => panic ! ( "Expected CreateTable" ) ,
9292+ }
9293+ }
9294+
9295+ #[ test]
9296+ fn parse_exclude_constraint_deferrable ( ) {
9297+ let sql =
9298+ "CREATE TABLE t (col INT, EXCLUDE USING gist (col WITH =) DEFERRABLE INITIALLY DEFERRED)" ;
9299+ match pg ( ) . verified_stmt ( sql) {
9300+ Statement :: CreateTable ( create_table) => {
9301+ assert_eq ! ( 1 , create_table. constraints. len( ) ) ;
9302+ match & create_table. constraints [ 0 ] {
9303+ TableConstraint :: Exclusion ( c) => {
9304+ let characteristics = c. characteristics . as_ref ( ) . unwrap ( ) ;
9305+ assert_eq ! ( characteristics. deferrable, Some ( true ) ) ;
9306+ assert_eq ! (
9307+ characteristics. initially,
9308+ Some ( DeferrableInitial :: Deferred )
9309+ ) ;
9310+ }
9311+ other => panic ! ( "Expected Exclusion, got {other:?}" ) ,
9312+ }
9313+ }
9314+ _ => panic ! ( "Expected CreateTable" ) ,
9315+ }
9316+ }
9317+
9318+ #[ test]
9319+ fn parse_exclude_constraint_in_alter_table ( ) {
9320+ let sql =
9321+ "ALTER TABLE t ADD CONSTRAINT no_overlap EXCLUDE USING gist (room WITH =)" ;
9322+ pg ( ) . verified_stmt ( sql) ;
9323+ }
9324+
9325+ #[ test]
9326+ fn roundtrip_exclude_constraint ( ) {
9327+ let sql = "CREATE TABLE t (CONSTRAINT no_overlap EXCLUDE USING gist (room WITH =, during WITH &&) INCLUDE (id) WHERE (active = true))" ;
9328+ pg ( ) . verified_stmt ( sql) ;
9329+ }
0 commit comments