STET

agent_patch

runs/2026-02-28__18-27-22__gpt-5-1-codex-mini/flux-pr-1900/flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/agent-logs/agent.patch

13544 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/ddl.rs b/app/src/ast/ddl.rs
index 059c619..5efe1ce 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/ddl.rs
+++ b/app/src/ast/ddl.rs
@@ -31,7 +31,7 @@ use sqlparser_derive::{Visit, VisitMut};
 use crate::ast::value::escape_single_quote_string;
 use crate::ast::{
     display_comma_separated, display_separated, CommentDef, CreateFunctionBody,
-    CreateFunctionUsing, DataType, Expr, FunctionBehavior, FunctionCalledOnNull,
+    CreateFunctionUsing, DataType, Expr, IndexColumn, FunctionBehavior, FunctionCalledOnNull,
     FunctionDeterminismSpecifier, FunctionParallel, Ident, MySQLColumnPosition, ObjectName,
     OperateFunctionArg, OrderByExpr, ProjectionSelect, SequenceOptions, SqlOption, Tag, Value,
     ValueWithSpan,
@@ -978,8 +978,8 @@ pub enum TableConstraint {
         ///
         /// [1]: IndexType
         index_type: Option<IndexType>,
-        /// Identifiers of the columns that are unique.
-        columns: Vec<Ident>,
+        /// Indexed columns that are unique.
+        columns: Vec<IndexColumn>,
         index_options: Vec<IndexOption>,
         characteristics: Option<ConstraintCharacteristics>,
         /// Optional Postgres nulls handling: `[ NULLS [ NOT ] DISTINCT ]`
@@ -1014,8 +1014,8 @@ pub enum TableConstraint {
         ///
         /// [1]: IndexType
         index_type: Option<IndexType>,
-        /// Identifiers of the columns that form the primary key.
-        columns: Vec<Ident>,
+        /// Indexed columns that form the primary key.
+        columns: Vec<IndexColumn>,
         index_options: Vec<IndexOption>,
         characteristics: Option<ConstraintCharacteristics>,
     },
@@ -1059,8 +1059,8 @@ pub enum TableConstraint {
         ///
         /// [1]: IndexType
         index_type: Option<IndexType>,
-        /// Referred column identifier list.
-        columns: Vec<Ident>,
+        /// Referred index columns.
+        columns: Vec<IndexColumn>,
     },
     /// MySQLs [fulltext][1] definition. Since the [`SPATIAL`][2] definition is exactly the same,
     /// and MySQL displays both the same way, it is part of this definition as well.
@@ -1082,8 +1082,8 @@ pub enum TableConstraint {
         index_type_display: KeyOrIndexDisplay,
         /// Optional index name.
         opt_index_name: Option<Ident>,
-        /// Referred column identifier list.
-        columns: Vec<Ident>,
+        /// Referred index columns.
+        columns: Vec<IndexColumn>,
     },
 }
 
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/spans.rs b/app/src/ast/spans.rs
index 14664b4..13609b4 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/spans.rs
+++ b/app/src/ast/spans.rs
@@ -25,7 +25,8 @@ use super::{
     AlterIndexOperation, AlterTableOperation, Array, Assignment, AssignmentTarget, AttachedToken,
     BeginEndStatements, CaseStatement, CloseCursor, ClusteredIndex, ColumnDef, ColumnOption,
     ColumnOptionDef, ConditionalStatementBlock, ConditionalStatements, ConflictTarget, ConnectBy,
-    ConstraintCharacteristics, CopySource, CreateIndex, CreateTable, CreateTableOptions, Cte,
+    ConstraintCharacteristics, CopySource, CreateIndex, IndexColumn, CreateTable, CreateTableOptions,
+    Cte,
     Delete, DoUpdate, ExceptSelectItem, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, FromTable,
     Function, FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList,
     FunctionArguments, GroupByExpr, HavingBound, IfStatement, IlikeSelectItem, Insert, Interpolate,
@@ -634,6 +635,14 @@ impl Spanned for ColumnOptionDef {
     }
 }
 
+impl Spanned for IndexColumn {
+    fn span(&self) -> Span {
+        self.column
+            .span()
+            .union_opt(&self.operator_class.as_ref().map(|i| i.span))
+    }
+}
+
 impl Spanned for TableConstraint {
     fn span(&self) -> Span {
         match self {
@@ -737,7 +746,7 @@ impl Spanned for CreateIndex {
             name.iter()
                 .map(|i| i.span())
                 .chain(core::iter::once(table_name.span()))
-                .chain(columns.iter().map(|i| i.column.span()))
+                .chain(columns.iter().map(|i| i.span()))
                 .chain(include.iter().map(|i| i.span))
                 .chain(with.iter().map(|i| i.span()))
                 .chain(predicate.iter().map(|i| i.span())),
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/parser/mod.rs b/app/src/parser/mod.rs
index 44bf58d..5168baf 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -8070,7 +8070,8 @@ impl<'a> Parser<'a> {
                 let index_name = self.parse_optional_ident()?;
                 let index_type = self.parse_optional_using_then_index_type()?;
 
-                let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+                let columns =
+                    self.parse_parenthesized_column_list(Mandatory, false)?;
                 let index_options = self.parse_index_options()?;
                 let characteristics = self.parse_constraint_characteristics()?;
                 Ok(Some(TableConstraint::Unique {
@@ -8092,7 +8093,8 @@ impl<'a> Parser<'a> {
                 let index_name = self.parse_optional_ident()?;
                 let index_type = self.parse_optional_using_then_index_type()?;
 
-                let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+                let columns =
+                    self.parse_parenthesized_index_column_list(Mandatory, false)?;
                 let index_options = self.parse_index_options()?;
                 let characteristics = self.parse_constraint_characteristics()?;
                 Ok(Some(TableConstraint::PrimaryKey {
@@ -8107,7 +8109,8 @@ impl<'a> Parser<'a> {
             Token::Word(w) if w.keyword == Keyword::FOREIGN => {
                 self.expect_keyword_is(Keyword::KEY)?;
                 let index_name = self.parse_optional_ident()?;
-                let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+                let columns =
+                    self.parse_parenthesized_column_list(Mandatory, false)?;
                 self.expect_keyword_is(Keyword::REFERENCES)?;
                 let foreign_table = self.parse_object_name(false)?;
                 let referred_columns = self.parse_parenthesized_column_list(Optional, false)?;
@@ -8170,7 +8173,8 @@ impl<'a> Parser<'a> {
                 };
 
                 let index_type = self.parse_optional_using_then_index_type()?;
-                let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+                let columns =
+                    self.parse_parenthesized_index_column_list(Mandatory, false)?;
 
                 Ok(Some(TableConstraint::Index {
                     display_as_key,
@@ -8199,7 +8203,8 @@ impl<'a> Parser<'a> {
 
                 let opt_index_name = self.parse_optional_ident()?;
 
-                let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+                let columns =
+                    self.parse_parenthesized_index_column_list(Mandatory, false)?;
 
                 Ok(Some(TableConstraint::FulltextOrSpatial {
                     fulltext,
@@ -10613,6 +10618,17 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parses a parenthesized comma-separated list of index column expressions.
+    pub fn parse_parenthesized_index_column_list(
+        &mut self,
+        optional: IsOptional,
+        allow_empty: bool,
+    ) -> Result<Vec<IndexColumn>, ParserError> {
+        self.parse_parenthesized_column_list_inner(optional, allow_empty, |p| {
+            p.parse_create_index_expr()
+        })
+    }
+
     /// Parses a parenthesized comma-separated list of columns using
     /// the provided function to parse each element.
     fn parse_parenthesized_column_list_inner<F, T>(
@@ -16527,6 +16543,20 @@ mod tests {
             }};
         }
 
+        fn index_column(name: &str) -> IndexColumn {
+            IndexColumn {
+                column: OrderByExpr {
+                    expr: Expr::Identifier(Ident::new(name)),
+                    options: OrderByOptions {
+                        asc: None,
+                        nulls_first: None,
+                    },
+                    with_fill: None,
+                },
+                operator_class: None,
+            }
+        }
+
         let dialect =
             TestedDialects::new(vec![Box::new(GenericDialect {}), Box::new(MySqlDialect {})]);
 
@@ -16537,7 +16567,7 @@ mod tests {
                 display_as_key: false,
                 name: None,
                 index_type: None,
-                columns: vec![Ident::new("c1")],
+                columns: vec![index_column("c1")],
             }
         );
 
@@ -16548,7 +16578,7 @@ mod tests {
                 display_as_key: true,
                 name: None,
                 index_type: None,
-                columns: vec![Ident::new("c1")],
+                columns: vec![index_column("c1")],
             }
         );
 
@@ -16559,7 +16589,7 @@ mod tests {
                 display_as_key: false,
                 name: Some(Ident::with_quote('\'', "index")),
                 index_type: None,
-                columns: vec![Ident::new("c1"), Ident::new("c2")],
+                columns: vec![index_column("c1"), index_column("c2")],
             }
         );
 
@@ -16570,7 +16600,7 @@ mod tests {
                 display_as_key: false,
                 name: None,
                 index_type: Some(IndexType::BTree),
-                columns: vec![Ident::new("c1")],
+                columns: vec![index_column("c1")],
             }
         );
 
@@ -16581,7 +16611,7 @@ mod tests {
                 display_as_key: false,
                 name: None,
                 index_type: Some(IndexType::Hash),
-                columns: vec![Ident::new("c1")],
+                columns: vec![index_column("c1")],
             }
         );
 
@@ -16592,7 +16622,7 @@ mod tests {
                 display_as_key: false,
                 name: Some(Ident::new("idx_name")),
                 index_type: Some(IndexType::BTree),
-                columns: vec![Ident::new("c1")],
+                columns: vec![index_column("c1")],
             }
         );
 
@@ -16603,7 +16633,7 @@ mod tests {
                 display_as_key: false,
                 name: Some(Ident::new("idx_name")),
                 index_type: Some(IndexType::Hash),
-                columns: vec![Ident::new("c1")],
+                columns: vec![index_column("c1")],
             }
         );
     }
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_mysql.rs b/app/tests/sqlparser_mysql.rs
index 540348f..eb52c07 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_mysql.rs
+++ b/app/tests/sqlparser_mysql.rs
@@ -659,13 +659,27 @@ fn parse_create_table_auto_increment() {
     }
 }
 
+fn simple_index_column(name: &str) -> IndexColumn {
+    IndexColumn {
+        column: OrderByExpr {
+            expr: Expr::Identifier(Ident::new(name)),
+            options: OrderByOptions {
+                asc: None,
+                nulls_first: None,
+            },
+            with_fill: None,
+        },
+        operator_class: None,
+    }
+}
+
 /// if `unique_index_type_display` is `Some` create `TableConstraint::Unique`
 ///  otherwise create `TableConstraint::Primary`
 fn table_constraint_unique_primary_ctor(
     name: Option<Ident>,
     index_name: Option<Ident>,
     index_type: Option<IndexType>,
-    columns: Vec<Ident>,
+    columns: Vec<IndexColumn>,
     index_options: Vec<IndexOption>,
     characteristics: Option<ConstraintCharacteristics>,
     unique_index_type_display: Option<KeyOrIndexDisplay>,
@@ -713,7 +727,7 @@ fn parse_create_table_primary_and_unique_key() {
                     Some(Ident::new("bar_key")),
                     None,
                     None,
-                    vec![Ident::new("bar")],
+                    vec![simple_index_column("bar")],
                     vec![],
                     None,
                     index_type_display,
@@ -776,7 +790,10 @@ fn parse_create_table_primary_and_unique_key_with_index_options() {
                     Some(Ident::new("constr")),
                     Some(Ident::new("index_name")),
                     None,
-                    vec![Ident::new("bar"), Ident::new("var")],
+                    vec![
+                        simple_index_column("bar"),
+                        simple_index_column("var"),
+                    ],
                     vec![
                         IndexOption::Using(IndexType::Hash),
                         IndexOption::Comment("yes, ".into()),
@@ -814,7 +831,7 @@ fn parse_create_table_primary_and_unique_key_with_index_type() {
                     None,
                     Some(Ident::new("index_name")),
                     Some(IndexType::BTree),
-                    vec![Ident::new("bar")],
+                    vec![simple_index_column("bar")],
                     vec![IndexOption::Using(IndexType::Hash)],
                     None,
                     index_type_display,