STET

agent_patch

runs/2026-02-28__18-27-22__gpt-5-4/flux-pr-1918/flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/agent-logs/agent.patch

8873 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/ddl.rs b/app/src/ast/ddl.rs
index 7e46a59..a95ba38 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/ddl.rs
+++ b/app/src/ast/ddl.rs
@@ -140,10 +140,10 @@ pub enum AlterTableOperation {
         name: Ident,
         drop_behavior: Option<DropBehavior>,
     },
-    /// `DROP [ COLUMN ] [ IF EXISTS ] <column_name> [ CASCADE ]`
+    /// `DROP [ COLUMN ] [ IF EXISTS ] <column_name> [, <column_name> ...] [ CASCADE ]`
     DropColumn {
         has_column_keyword: bool,
-        column_name: Ident,
+        column_names: Vec<Ident>,
         if_exists: bool,
         drop_behavior: Option<DropBehavior>,
     },
@@ -631,7 +631,7 @@ impl fmt::Display for AlterTableOperation {
             AlterTableOperation::DropIndex { name } => write!(f, "DROP INDEX {name}"),
             AlterTableOperation::DropColumn {
                 has_column_keyword,
-                column_name,
+                column_names,
                 if_exists,
                 drop_behavior,
             } => write!(
@@ -639,7 +639,7 @@ impl fmt::Display for AlterTableOperation {
                 "DROP {}{}{}{}",
                 if *has_column_keyword { "COLUMN " } else { "" },
                 if *if_exists { "IF EXISTS " } else { "" },
-                column_name,
+                display_comma_separated(column_names),
                 match drop_behavior {
                     None => "",
                     Some(DropBehavior::Restrict) => " RESTRICT",
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/spans.rs b/app/src/ast/spans.rs
index 1d790ab..a6f0062 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/spans.rs
+++ b/app/src/ast/spans.rs
@@ -1112,10 +1112,10 @@ impl Spanned for AlterTableOperation {
             } => name.span,
             AlterTableOperation::DropColumn {
                 has_column_keyword: _,
-                column_name,
+                column_names,
                 if_exists: _,
                 drop_behavior: _,
-            } => column_name.span,
+            } => union_spans(column_names.iter().map(|column_name| column_name.span)),
             AlterTableOperation::AttachPartition { partition } => partition.span(),
             AlterTableOperation::DetachPartition { partition } => partition.span(),
             AlterTableOperation::FreezePartition {
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/dialect/mod.rs b/app/src/dialect/mod.rs
index 3345380..0a101ef 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/dialect/mod.rs
+++ b/app/src/dialect/mod.rs
@@ -1063,6 +1063,12 @@ pub trait Dialect: Debug + Any {
         false
     }
 
+    /// Returns true if the dialect supports dropping multiple columns in a single
+    /// `ALTER TABLE ... DROP COLUMN` operation using a comma-separated column list.
+    fn supports_multiple_drop_columns(&self) -> bool {
+        false
+    }
+
     /// Returns true if the dialect supports the `USING` clause in an `ALTER COLUMN` statement.
     /// Example:
     ///  ```sql
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/dialect/snowflake.rs b/app/src/dialect/snowflake.rs
index ee770b0..238b82b 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/dialect/snowflake.rs
+++ b/app/src/dialect/snowflake.rs
@@ -364,6 +364,10 @@ impl Dialect for SnowflakeDialect {
     fn supports_space_separated_column_options(&self) -> bool {
         true
     }
+
+    fn supports_multiple_drop_columns(&self) -> bool {
+        true
+    }
 }
 
 fn parse_file_staging_command(kw: Keyword, parser: &mut Parser) -> Result<Statement, ParserError> {
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/parser/mod.rs b/app/src/parser/mod.rs
index 32f8a97..b0dabef 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -8675,11 +8675,15 @@ impl<'a> Parser<'a> {
             } else {
                 let has_column_keyword = self.parse_keyword(Keyword::COLUMN); // [ COLUMN ]
                 let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
-                let column_name = self.parse_identifier()?;
+                let column_names = if self.dialect.supports_multiple_drop_columns() {
+                    self.parse_comma_separated(Parser::parse_identifier)?
+                } else {
+                    vec![self.parse_identifier()?]
+                };
                 let drop_behavior = self.parse_optional_drop_behavior();
                 AlterTableOperation::DropColumn {
                     has_column_keyword,
-                    column_name,
+                    column_names,
                     if_exists,
                     drop_behavior,
                 }
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_common.rs b/app/tests/sqlparser_common.rs
index 1bdd302..c1c8484 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_common.rs
+++ b/app/tests/sqlparser_common.rs
@@ -5000,11 +5000,11 @@ fn parse_alter_table_drop_column() {
         match alter_table_op(verified_stmt(&format!("ALTER TABLE tab {constraint_text}"))) {
             AlterTableOperation::DropColumn {
                 has_column_keyword: true,
-                column_name,
+                column_names,
                 if_exists,
                 drop_behavior,
             } => {
-                assert_eq!("is_active", column_name.to_string());
+                assert_eq!(vec![Ident::new("is_active")], column_names);
                 assert!(if_exists);
                 match drop_behavior {
                     None => assert!(constraint_text.ends_with(" is_active")),
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_mysql.rs b/app/tests/sqlparser_mysql.rs
index 9224a00..79e2259 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_mysql.rs
+++ b/app/tests/sqlparser_mysql.rs
@@ -2876,7 +2876,7 @@ fn parse_alter_table_with_algorithm() {
                 vec![
                     AlterTableOperation::DropColumn {
                         has_column_keyword: true,
-                        column_name: Ident::new("password_digest"),
+                        column_names: vec![Ident::new("password_digest")],
                         if_exists: false,
                         drop_behavior: None,
                     },
@@ -2924,7 +2924,7 @@ fn parse_alter_table_with_lock() {
                 vec![
                     AlterTableOperation::DropColumn {
                         has_column_keyword: true,
-                        column_name: Ident::new("password_digest"),
+                        column_names: vec![Ident::new("password_digest")],
                         if_exists: false,
                         drop_behavior: None,
                     },
diff --git a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_snowflake.rs b/app/tests/sqlparser_snowflake.rs
index 8a1558b..fba5900 100644
--- a/tmp/agent-patch-flux-pr-1918.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_snowflake.rs
+++ b/app/tests/sqlparser_snowflake.rs
@@ -1646,6 +1646,39 @@ fn test_alter_table_clustering() {
     snowflake_and_generic().verified_stmt("ALTER TABLE tbl RESUME RECLUSTER");
 }
 
+#[test]
+fn test_alter_table_drop_multiple_columns() {
+    let sql = "ALTER TABLE tab DROP COLUMN c1, c2, c3";
+    match alter_table_op(snowflake_and_generic().verified_stmt(sql)) {
+        AlterTableOperation::DropColumn {
+            has_column_keyword,
+            column_names,
+            if_exists,
+            drop_behavior,
+        } => {
+            assert!(has_column_keyword);
+            assert_eq!(
+                column_names,
+                vec![Ident::new("c1"), Ident::new("c2"), Ident::new("c3")]
+            );
+            assert!(!if_exists);
+            assert_eq!(drop_behavior, None);
+        }
+        _ => unreachable!(),
+    }
+
+    snowflake_and_generic().one_statement_parses_to(sql, sql);
+}
+
+#[test]
+fn test_alter_table_drop_multiple_columns_requires_supported_dialect() {
+    let res = parse_sql_statements("ALTER TABLE tab DROP COLUMN c1, c2");
+    assert_eq!(
+        res.unwrap_err().to_string(),
+        "sql parser error: Expected: end of statement, found: ,"
+    );
+}
+
 #[test]
 fn test_alter_iceberg_table() {
     snowflake_and_generic().verified_stmt("ALTER ICEBERG TABLE tbl DROP CLUSTERING KEY");